首頁 > web前端 > js教程 > '腳本錯誤”是什麼意思?

'腳本錯誤”是什麼意思?

Joseph Gordon-Levitt
發布: 2025-02-15 11:45:12
原創
991 人瀏覽過

What the Heck Does

核心要點

  • 瀏覽器在 JavaScript 文件來自不同來源時,會向 onerror 回調函數發送“腳本錯誤”消息。這是出於安全考慮,防止意外洩漏潛在敏感信息。
  • 要深入了解由不同來源的文件提供的 JavaScript 錯誤,必須採取兩個步驟:添加 crossorigin="anonymous" 腳本屬性和添加跨域 HTTP 頭。這允許任何來源獲取文件,並且腳本觸發的任何錯誤都將報告給 window.onerror
  • 如果無法調整腳本的 HTTP 頭,則可以使用 try/catch 作為替代方法。通過將第三方代碼包裝在 try/catch 塊中,可以深入了解跨域腳本拋出的錯誤。但是,如果可能,仍然建議設置 CORS 屬性和頭。

本文與 Sentry.io 合作創作。感謝您支持使 SitePoint 成為可能的合作夥伴。

如果您之前使用過 JavaScript 的 onerror 事件,您可能遇到過以下情況:

腳本錯誤。

當錯誤源於來自不同來源(不同的域名、端口或協議)的 JavaScript 文件時,瀏覽器會將“腳本錯誤”發送到 onerror 回調函數。這很痛苦,因為即使發生了錯誤,您也不知道錯誤是什麼,也不知道錯誤源於哪個代碼。而 window.onerror 的全部目的是深入了解應用程序中未捕獲的錯誤。

原因:跨域腳本

為了更好地理解正在發生的事情,請考慮以下示例 HTML 文檔,假設它來自 http://example.com/test

<!DOCTYPE html>
<html>
<head>
  <title>example.com/test</title>
</head>
<body>
  <🎜>
  <🎜>
</body>
</html>
登入後複製
登入後複製

這是 http://another-domain.com/app.js 的內容。它聲明了一個名為 foo 的單個函數,其調用將始終拋出 ReferenceError

// another-domain.com/app.js
function foo() {
  bar(); // ReferenceError: bar 不是函数
}
登入後複製
登入後複製

當此文檔在瀏覽器中加載並執行 JavaScript 時,以下內容將輸出到控制台(通過 window.onerror 回調函數記錄):

"腳本錯誤。", "", 0, 0, undefined

這不是 JavaScript 錯誤——瀏覽器故意出於安全原因隱藏來自不同來源的腳本文件的錯誤。這是為了避免腳本無意中將潛在的敏感信息洩漏到它無法控制的 onerror 回調函數中。因此,瀏覽器只允許 window.onerror 深入了解源於同一域的錯誤。我們只知道發生了錯誤——除此之外什麼都不知道!

我不是壞人,真的!

儘管瀏覽器的意圖良好,但您希望深入了解由不同來源的腳本拋出的錯誤,有一些非常好的理由:

  1. 您的應用程序 JavaScript 文件來自不同的主機名(例如,static.sentry.io/app.js)。
  2. 您正在使用來自社區 CDN(如 cdnjs 或 Google 託管庫)提供的庫。
  3. 您正在使用僅從外部服務器提供的商業第三方 JavaScript 庫。

但別擔心!深入了解由這些文件提供的 JavaScript 錯誤只需要一些簡單的調整。

解決方案:CORS 屬性和頭

為了了解由不同來源的腳本拋出的 JavaScript 異常,您必須執行兩件事。

1. 添加 crossorigin="anonymous" 腳本屬性

<!DOCTYPE html>
<html>
<head>
  <title>example.com/test</title>
</head>
<body>
  <🎜>
  <🎜>
</body>
</html>
登入後複製
登入後複製

這告訴瀏覽器目標文件應該“匿名”獲取。這意味著當請求此文件時,瀏覽器不會向服務器傳輸任何潛在的用戶識別信息,如 Cookie 或 HTTP 憑據。

2. 添加跨域 HTTP 頭

// another-domain.com/app.js
function foo() {
  bar(); // ReferenceError: bar 不是函数
}
登入後複製
登入後複製

CORS 是跨域資源共享的縮寫,它是一組 API(主要是 HTTP 頭),用於規定如何跨域下載和提供文件。

通過設置 <code>Access-Control-Allow-Origin: *</code>,服務器向瀏覽器指示任何來源都可以獲取此文件。或者,您可以將其限制為您控制的已知來源:

<🎜>
登入後複製

一旦完成了這兩個步驟,此腳本觸發的任何錯誤都將報告給 window.onerror,就像任何常規的同域腳本一樣。因此,onerror 示例將不再是“腳本錯誤”,而是:

<code>Access-Control-Allow-Origin: *</code>
登入後複製

就是這樣! “腳本錯誤”將不再困擾您和您的團隊。

替代方案:try/catch

有時我們無法調整我們的 Web 應用程序正在使用的腳本的 HTTP 頭。在這種情況下,有一種替代方法:使用 try/catch

再次考慮原始示例,這次使用 try/catch

$ curl --head https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.js | \
    grep -i "access-control-allow-origin"

Access-Control-Allow-Origin: *
登入後複製

為了後代考慮,some-domain.com/app.js 再次如下所示:

<code>"ReferenceError: bar 未定义", "http://another-domain.com/app.js", 2, 1, [Object Error]</code>
登入後複製

運行示例 HTML 將輸出以下兩個條目到控制台:

window.onerror = function (message, url, line, column, error) {
  console.log(message, url, line, column, error);
}

try {
  foo(); // 调用 app.js 中声明的函数
} catch (e) {
  console.log(e);
  throw e; // 故意重新抛出(由 window.onerror 捕获)
}
登入後複製

第一個控制台語句——來自 try/catch——設法獲取了一個錯誤對象,其中包含類型、消息和堆棧跟踪,包括文件名和行號。來自 window.onerror 的第二個控制台語句再次只能輸出“腳本錯誤”。

現在,這是否意味著您需要嘗試捕獲所有代碼?可能不是。如果您能輕鬆更改 HTML 並指定 CDN 上的 CORS 頭,最好這樣做並堅持使用 window.onerror

但是,如果您不控制這些資源,使用 try/catch 包裝第三方代碼是獲得對跨域腳本拋出的錯誤的深入了解的可靠(儘管很繁瑣)的方法。

注意:默認情況下,Sentry 的 JavaScript SDK raven.js 會仔細地檢測內置方法,以嘗試自動將您的代碼包裝在 try/catch 塊中。這樣做是為了嘗試捕獲所有腳本的錯誤消息和堆棧跟踪,無論它們來自哪個來源。如果可能,仍然建議設置 CORS 屬性和頭。

當然,有很多商業和開源工具可以為您完成所有繁重的工作。 (噓:您可能想嘗試使用 Sentry 調試 JavaScript。)

就是這樣!祝您錯誤監控愉快。

腳本錯誤常見問題解答

(此處省略了FAQ部分,因為篇幅過長,且與文章主題關聯性較弱,可以根據需要自行添加或修改FAQ)

以上是'腳本錯誤”是什麼意思?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板