<script>: 指令碼元素

Baseline 廣泛可用 *

此特性已相當成熟,可在許多裝置和瀏覽器版本上使用。自 ⁨2015 年 7 月⁩以來,各瀏覽器均已提供此特性。

* 此特性的某些部分可能存在不同級別的支援。

<script> HTML 元素用於嵌入可執行程式碼或資料;通常用於嵌入或引用 JavaScript 程式碼。<script> 元素也可以與其他語言一起使用,例如 WebGL 的 GLSL 著色器程式語言和 JSON

屬性

此元素包含全域性屬性

async

對於經典指令碼,如果存在 async 屬性,則經典指令碼將與解析並行獲取,並儘快進行評估。

對於模組指令碼,如果存在 async 屬性,則指令碼及其所有依賴項將與解析並行獲取,並儘快進行評估。

警告: 對於經典指令碼,如果缺少 src 屬性(即用於內聯指令碼),則不得使用此屬性,在這種情況下它將無效。

此屬性允許消除阻塞解析器的 JavaScript,在這種情況下,瀏覽器必須在繼續解析之前載入和評估指令碼。defer 在這種情況下具有類似的效果。

如果該屬性與 defer 屬性一起指定,則該元素將表現得如同僅指定了 async 屬性一樣。

這是一個布林屬性:元素上布林屬性的存在表示真值,屬性的缺失表示假值。

有關瀏覽器支援的說明,請參閱瀏覽器相容性。另請參閱 asm.js 的非同步指令碼

attributionsrc 實驗性

指定您希望瀏覽器隨指令碼資源請求一起傳送 Attribution-Reporting-Eligible 標頭。在伺服器端,這用於觸發在響應中傳送 Attribution-Reporting-Register-SourceAttribution-Reporting-Register-Trigger 標頭,以分別註冊基於 JavaScript 的歸因源歸因觸發器。應返回哪個響應標頭取決於觸發註冊的 Attribution-Reporting-Eligible 標頭的值。

注意: 另外,基於 JavaScript 的歸因源或觸發器可以透過傳送包含 attributionReporting 選項的 fetch() 請求(直接在 fetch() 呼叫上設定或在傳遞給 fetch() 呼叫的 Request 物件上設定),或者透過傳送呼叫了 setAttributionReporting()XMLHttpRequest 來註冊。

您可以設定此屬性的兩個版本

  • 布林值,即只有 attributionsrc 名稱。這指定您希望將 Attribution-Reporting-Eligible 標頭髮送到 src 屬性指向的同一伺服器。當您在同一伺服器上處理歸因源或觸發器註冊時,這很好。註冊歸因觸發器時,此屬性是可選的,如果省略,將使用空字串值。

  • 包含一個或多個 URL 的值,例如

    html
    <script
      src="myscript.js"
      attributionsrc="https://a.example/register-source https://b.example/register-source"></script>
    

    這在請求的資源不在您控制的伺服器上,或者您只想在不同的伺服器上處理歸因源註冊的情況下很有用。在這種情況下,您可以指定一個或多個 URL 作為 attributionsrc 的值。當資源請求發生時,Attribution-Reporting-Eligible 標頭將除了資源源之外,還會發送到 attributionSrc 中指定的 URL。這些 URL 隨後可以根據需要響應 Attribution-Reporting-Register-SourceAttribution-Reporting-Register-Trigger 標頭以完成註冊。

    注意:指定多個 URL 意味著可以在同一功能上註冊多個歸因源。例如,您可能正在嘗試衡量不同廣告系列的成功,這涉及生成關於不同資料的不同報告。

有關更多詳細資訊,請參閱 歸因報告 API

阻塞

此屬性明確指示某些操作應在指令碼執行之前被阻塞。要阻塞的操作必須是空格分隔的阻塞令牌列表。目前只有一個令牌

  • render: 螢幕上的內容渲染被阻塞。

注意: 只有文件 <head> 中的 script 元素才可能阻塞渲染。指令碼預設不阻塞渲染;如果 script 元素不包含 type="module"asyncdefer,則它會阻塞解析,而不是渲染。如果此類 script 元素透過指令碼動態新增,則必須設定 blocking = "render" 才能使其阻塞渲染。

crossorigin

對於不透過標準 CORS 檢查的指令碼,普通 script 元素向 window.onerror 傳遞最少的資訊。為了允許使用單獨域進行靜態媒體的站點進行錯誤日誌記錄,請使用此屬性。有關其有效引數的更詳細說明,請參閱CORS 設定屬性

defer

此布林屬性用於指示瀏覽器,指令碼應在文件解析後但在觸發 DOMContentLoaded 事件之前執行。

帶有 defer 屬性的指令碼將阻止 DOMContentLoaded 事件觸發,直到指令碼載入並完成評估。

警告: 如果缺少 src 屬性(即用於內聯指令碼),則不得使用此屬性,在這種情況下它將無效。

defer 屬性對模組指令碼無效——它們預設會延遲。

帶有 defer 屬性的指令碼將按照它們在文件中出現的順序執行。

此屬性允許消除阻塞解析器的 JavaScript,在這種情況下,瀏覽器必須在繼續解析之前載入和評估指令碼。async 在這種情況下具有類似的效果。

如果該屬性與 async 屬性一起指定,則該元素將表現得如同僅指定了 async 屬性一樣。

fetchpriority

提供在獲取外部指令碼時要使用的相對優先順序的提示。允許的值

high

以相對於其他外部指令碼的較高優先順序獲取外部指令碼。

low

以相對於其他外部指令碼的較低優先順序獲取外部指令碼。

auto

不對獲取優先順序設定偏好。這是預設值。如果未設定值或設定了無效值,則使用此值。

有關更多資訊,請參閱 HTMLScriptElement.fetchPriority

integrity

此屬性包含內聯元資料,使用者代理可以使用它來驗證獲取的資源是否已在沒有意外操作的情況下交付。當 src 屬性缺失時,不得指定此屬性。請參閱子資源完整性

nomodule

此布林屬性用於指示在支援 ES 模組的瀏覽器中不應執行該指令碼——實際上,這可以用於向不支援模組化 JavaScript 程式碼的舊版瀏覽器提供回退指令碼。

nonce

一個加密的 nonce(一次性數字)以允許 script-src Content-Security-Policy 中的指令碼。伺服器每次傳輸策略時都必須生成唯一的 nonce 值。提供一個無法猜測的 nonce 至關重要,否則繞過資源的策略將是微不足道的。

referrerpolicy

指示在獲取指令碼或指令碼獲取的資源時要傳送的 引用者

  • no-referrer:將不傳送 Referer 頭。
  • no-referrer-when-downgrade:將不向沒有 TLS (HTTPS) 的傳送 Referer 頭。
  • origin:傳送的引用者將僅限於引用頁面的源:其方案主機
  • origin-when-cross-origin:傳送到其他源的引用者將僅限於方案、主機和埠。同一源上的導航仍將包含路徑。
  • same-origin:將為同源傳送引用者,但跨域請求將不包含引用者資訊。
  • strict-origin:僅當協議安全級別保持不變 (HTTPS→HTTPS) 時,才將文件的源作為引用者傳送,但不要將其傳送到安全性較低的目標 (HTTPS→HTTP)。
  • strict-origin-when-cross-origin(預設):執行同源請求時傳送完整 URL,僅當協議安全級別保持不變 (HTTPS→HTTPS) 時傳送源,不向安全性較低的目標 (HTTPS→HTTP) 傳送任何頭。
  • unsafe-url:引用者將包含源路徑(但不包含片段密碼使用者名稱)。此值不安全,因為它會將 TLS 保護資源的源和路徑洩漏到不安全的源。

注意: 空字串值("")是預設值,也是在不支援 referrerpolicy 時使用的回退值。如果 referrerpolicy 未在 <script> 元素上顯式指定,它將採用更高級別的引用者策略,即在整個文件或域上設定的策略。如果更高級別的策略不可用,則空字串被視為等同於 strict-origin-when-cross-origin

src

此屬性指定外部指令碼的 URI;這可以作為直接在文件中嵌入指令碼的替代方案。

type

此屬性指示所代表的指令碼型別。此屬性的值將是以下之一

屬性未設定(預設),空字串,或 JavaScript MIME 型別

表示指令碼是“經典指令碼”,包含 JavaScript 程式碼。如果指令碼引用的是 JavaScript 程式碼而不是指定 MIME 型別,建議作者省略該屬性。JavaScript MIME 型別在 IANA 媒體型別規範中列出

importmap

此值表示元素主體包含一個匯入對映。匯入對映是一個 JSON 物件,開發人員可以使用它來控制瀏覽器在匯入JavaScript 模組時如何解析模組說明符。

模組

此值導致程式碼被視為 JavaScript 模組。指令碼內容的處理被延遲。charsetdefer 屬性無效。有關使用 module 的資訊,請參閱我們的JavaScript 模組指南。與經典指令碼不同,模組指令碼需要使用 CORS 協議進行跨域獲取。

speculationrules 實驗性

此值表示元素主體包含推測規則。推測規則採用 JSON 物件的形式,用於確定瀏覽器應預取或預渲染哪些資源。這是 推測規則 API 的一部分。

任何其他值

嵌入內容被視為資料塊,不會被瀏覽器處理。開發人員必須使用有效的非 JavaScript MIME 型別來表示資料塊。所有其他屬性都將被忽略,包括 src 屬性。

已棄用屬性

charset 已棄用

如果存在,其值必須與 utf-8 進行 ASCII 不區分大小寫的匹配。無需指定 charset 屬性,因為文件必須使用 UTF-8,並且 script 元素繼承其文件的字元編碼。

language 已棄用 非標準

type 屬性一樣,此屬性標識正在使用的指令碼語言。然而,與 type 屬性不同,此屬性的可能值從未標準化。應改用 type 屬性。

注意

沒有 asyncdefertype="module" 屬性的指令碼,以及沒有 type="module" 屬性的內聯指令碼,會在瀏覽器繼續解析頁面之前立即獲取和執行。

指令碼應以 text/javascript MIME 型別提供,但瀏覽器對此比較寬鬆,只有當指令碼以影像型別(image/*)、影片型別(video/*)、音訊型別(audio/*)或 text/csv 提供時才會阻止它們。如果指令碼被阻止,則會向元素髮送 error 事件;否則,會發送 load 事件。

示例

基本用法

此示例展示瞭如何使用 <script> 元素匯入(外部)指令碼

html
<script src="javascript.js"></script>

以下示例展示瞭如何將(內聯)指令碼放入 <script> 元素中

html
<script>
  alert("Hello World!");
</script>

async 和 defer

使用 async 屬性載入的指令碼將在指令碼獲取時下載指令碼,而不會阻塞頁面。但是,一旦下載完成,指令碼將執行,這會阻塞頁面的渲染。這意味著在指令碼執行完成之前,網頁上的其餘內容無法被處理和顯示給使用者。您無法保證指令碼會以任何特定的順序執行。當頁面中的指令碼彼此獨立執行且不依賴於頁面上的任何其他指令碼時,最好使用 async

使用 defer 屬性載入的指令碼將按照它們在頁面中出現的順序載入。它們不會執行,直到頁面內容全部載入完畢,這在您的指令碼依賴於 DOM 存在時很有用(例如,它們修改頁面上的一個或多個元素)。

以下是不同指令碼載入方法及其對頁面意味著什麼的視覺表示

How the three script loading method work: default has parsing blocked while JavaScript is fetched and executed. With async, the parsing pauses for execution only. With defer, parsing isn't paused, but execution on happens after everything is else is parsed.

此圖片來自 HTML 規範,根據 CC BY 4.0 許可條款複製並裁剪為簡化版本。

例如,如果您有以下指令碼元素

html
<script async src="js/vendor/jquery.js"></script>
<script async src="js/script2.js"></script>
<script async src="js/script3.js"></script>

您無法依賴指令碼的載入順序。jquery.js 可能在 script2.jsscript3.js 之前或之後載入,如果出現這種情況,這些指令碼中任何依賴於 jquery 的函式都會產生錯誤,因為在指令碼執行時 jquery 將未定義。

當您需要載入大量後臺指令碼並希望儘快將它們部署到位時,應該使用 async。例如,您可能有一些遊戲資料檔案需要載入,這些檔案在遊戲真正開始時會需要,但目前您只想繼續顯示遊戲介紹、標題和大廳,而不希望它們被指令碼載入阻塞。

使用 defer 屬性載入的指令碼(見下文)將按照它們在頁面中出現的順序執行,並在指令碼和內容下載後立即執行它們

html
<script defer src="js/vendor/jquery.js"></script>
<script defer src="js/script2.js"></script>
<script defer src="js/script3.js"></script>

在第二個示例中,我們可以確定 jquery.js 將在 script2.jsscript3.js 之前載入,並且 script2.js 將在 script3.js 之前載入。它們不會執行,直到頁面內容全部載入完畢,這在您的指令碼依賴於 DOM 存在時很有用(例如,它們修改頁面上的一個或多個元素)。

總結

  • asyncdefer 都指示瀏覽器在單獨的執行緒中下載指令碼,而頁面的其餘部分(DOM 等)正在下載,因此在獲取過程中頁面載入不會被阻塞。
  • 帶有 async 屬性的指令碼將在下載完成後立即執行。這會阻塞頁面並且不保證任何特定的執行順序。
  • 帶有 defer 屬性的指令碼將按照它們在頁面中的順序載入,並且只有在所有內容都載入完成後才會執行。
  • 如果您的指令碼應該立即執行並且沒有任何依賴關係,那麼請使用 async
  • 如果您的指令碼需要等待解析並依賴於其他指令碼和/或 DOM 的存在,請使用 defer 載入它們,並將它們相應的 <script> 元素按照您希望瀏覽器執行它們的順序放置。

模組回退

支援 type 屬性的 module 值的瀏覽器會忽略任何帶有 nomodule 屬性的指令碼。這使您能夠使用模組指令碼,同時為不支援的瀏覽器提供標記為 nomodule 的回退指令碼。

html
<script type="module" src="main.js"></script>
<script nomodule src="fallback.js"></script>

使用 importmap 匯入模組

在指令碼中匯入模組時,如果您不使用 type=importmap 功能,那麼每個模組都必須使用絕對或相對 URL 的模組說明符進行匯入。在下面的示例中,第一個模組說明符是絕對 URL,而第二個("./shapes/square.js")相對於文件的基本 URL 進行解析。

js
import { name as circleName } from "https://example.com/shapes/circle.js";
import { name as squareName, draw } from "./shapes/square.js";

匯入對映允許您提供一個對映,如果匹配,可以替換模組說明符中的文字。下面的匯入對映定義了鍵 circlesquare,它們可以作為上面顯示的模組說明符的別名。

html
<script type="importmap">
  {
    "imports": {
      "circle": "https://example.com/shapes/circle.js",
      "square": "./shapes/square.js"
    }
  }
</script>

這允許我們使用模組說明符中的名稱(而不是絕對或相對 URL)匯入模組。

js
import { name as circleName } from "circle";
import { name as squareName, draw } from "square";

有關匯入對映功能的更多示例,請參閱 JavaScript 模組指南中的使用匯入對映匯入模組部分。

在 HTML 中嵌入資料

您還可以透過在 type 屬性中指定有效的非 JavaScript MIME 型別,使用 <script> 元素透過伺服器端渲染將資料嵌入 HTML。

html
<!-- Generated by the server -->
<script id="data" type="application/json">
  {
    "userId": 1234,
    "userName": "Maria Cruz",
    "memberSince": "2000-01-01T00:00:00.000Z"
  }
</script>

<!-- Static -->
<script>
  const userInfo = JSON.parse(document.getElementById("data").text);
  console.log("User information: %o", userInfo);
</script>

阻塞渲染直到指令碼被獲取和執行

您可以在 blocking 屬性中包含 render 令牌;頁面的渲染將被阻塞,直到指令碼被獲取和執行。在下面的示例中,我們阻塞了一個非同步指令碼的渲染,這樣指令碼就不會阻塞解析,但保證在渲染開始之前被評估。

html
<script blocking="render" async src="async-script.js"></script>

技術摘要

內容類別 元資料內容流內容短語內容
允許內容 動態指令碼,例如 text/javascript
標籤省略 無,起始標籤和結束標籤都必須存在。
允許父級 任何接受元資料內容的元素,或任何接受短語內容的元素。
隱式 ARIA 角色 沒有對應的角色
允許的 ARIA 角色 不允許 role
DOM 介面 HTMLScriptElement

規範

規範
HTML
# 指令碼元素

瀏覽器相容性

另見