<script>: 指令碼元素
Baseline 廣泛可用 *
<script> HTML 元素用於嵌入可執行程式碼或資料;通常用於嵌入或引用 JavaScript 程式碼。<script> 元素也可以與其他語言一起使用,例如 WebGL 的 GLSL 著色器程式語言和 JSON。
屬性
此元素包含全域性屬性。
async-
對於經典指令碼,如果存在
async屬性,則經典指令碼將與解析並行獲取,並儘快進行評估。對於模組指令碼,如果存在
async屬性,則指令碼及其所有依賴項將與解析並行獲取,並儘快進行評估。警告: 對於經典指令碼,如果缺少
src屬性(即用於內聯指令碼),則不得使用此屬性,在這種情況下它將無效。此屬性允許消除阻塞解析器的 JavaScript,在這種情況下,瀏覽器必須在繼續解析之前載入和評估指令碼。
defer在這種情況下具有類似的效果。如果該屬性與
defer屬性一起指定,則該元素將表現得如同僅指定了async屬性一樣。這是一個布林屬性:元素上布林屬性的存在表示真值,屬性的缺失表示假值。
有關瀏覽器支援的說明,請參閱瀏覽器相容性。另請參閱 asm.js 的非同步指令碼。
attributionsrc實驗性-
指定您希望瀏覽器隨指令碼資源請求一起傳送
Attribution-Reporting-Eligible標頭。在伺服器端,這用於觸發在響應中傳送Attribution-Reporting-Register-Source或Attribution-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-Source或Attribution-Reporting-Register-Trigger標頭以完成註冊。注意:指定多個 URL 意味著可以在同一功能上註冊多個歸因源。例如,您可能正在嘗試衡量不同廣告系列的成功,這涉及生成關於不同資料的不同報告。
有關更多詳細資訊,請參閱 歸因報告 API。
-
阻塞-
此屬性明確指示某些操作應在指令碼執行之前被阻塞。要阻塞的操作必須是空格分隔的阻塞令牌列表。目前只有一個令牌
render: 螢幕上的內容渲染被阻塞。
注意: 只有文件
<head>中的script元素才可能阻塞渲染。指令碼預設不阻塞渲染;如果script元素不包含type="module"、async或defer,則它會阻塞解析,而不是渲染。如果此類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 模組。指令碼內容的處理被延遲。
charset和defer屬性無效。有關使用module的資訊,請參閱我們的JavaScript 模組指南。與經典指令碼不同,模組指令碼需要使用 CORS 協議進行跨域獲取。 speculationrules實驗性-
此值表示元素主體包含推測規則。推測規則採用 JSON 物件的形式,用於確定瀏覽器應預取或預渲染哪些資源。這是 推測規則 API 的一部分。
- 任何其他值
-
嵌入內容被視為資料塊,不會被瀏覽器處理。開發人員必須使用有效的非 JavaScript MIME 型別來表示資料塊。所有其他屬性都將被忽略,包括
src屬性。
已棄用屬性
charset已棄用-
如果存在,其值必須與
utf-8進行 ASCII 不區分大小寫的匹配。無需指定charset屬性,因為文件必須使用 UTF-8,並且script元素繼承其文件的字元編碼。 language已棄用 非標準-
與
type屬性一樣,此屬性標識正在使用的指令碼語言。然而,與type屬性不同,此屬性的可能值從未標準化。應改用type屬性。
注意
沒有 async、defer 或 type="module" 屬性的指令碼,以及沒有 type="module" 屬性的內聯指令碼,會在瀏覽器繼續解析頁面之前立即獲取和執行。
指令碼應以 text/javascript MIME 型別提供,但瀏覽器對此比較寬鬆,只有當指令碼以影像型別(image/*)、影片型別(video/*)、音訊型別(audio/*)或 text/csv 提供時才會阻止它們。如果指令碼被阻止,則會向元素髮送 error 事件;否則,會發送 load 事件。
示例
基本用法
此示例展示瞭如何使用 <script> 元素匯入(外部)指令碼
<script src="javascript.js"></script>
以下示例展示瞭如何將(內聯)指令碼放入 <script> 元素中
<script>
alert("Hello World!");
</script>
async 和 defer
使用 async 屬性載入的指令碼將在指令碼獲取時下載指令碼,而不會阻塞頁面。但是,一旦下載完成,指令碼將執行,這會阻塞頁面的渲染。這意味著在指令碼執行完成之前,網頁上的其餘內容無法被處理和顯示給使用者。您無法保證指令碼會以任何特定的順序執行。當頁面中的指令碼彼此獨立執行且不依賴於頁面上的任何其他指令碼時,最好使用 async。
使用 defer 屬性載入的指令碼將按照它們在頁面中出現的順序載入。它們不會執行,直到頁面內容全部載入完畢,這在您的指令碼依賴於 DOM 存在時很有用(例如,它們修改頁面上的一個或多個元素)。
以下是不同指令碼載入方法及其對頁面意味著什麼的視覺表示

此圖片來自 HTML 規範,根據 CC BY 4.0 許可條款複製並裁剪為簡化版本。
例如,如果您有以下指令碼元素
<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.js 和 script3.js 之前或之後載入,如果出現這種情況,這些指令碼中任何依賴於 jquery 的函式都會產生錯誤,因為在指令碼執行時 jquery 將未定義。
當您需要載入大量後臺指令碼並希望儘快將它們部署到位時,應該使用 async。例如,您可能有一些遊戲資料檔案需要載入,這些檔案在遊戲真正開始時會需要,但目前您只想繼續顯示遊戲介紹、標題和大廳,而不希望它們被指令碼載入阻塞。
使用 defer 屬性載入的指令碼(見下文)將按照它們在頁面中出現的順序執行,並在指令碼和內容下載後立即執行它們
<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.js 和 script3.js 之前載入,並且 script2.js 將在 script3.js 之前載入。它們不會執行,直到頁面內容全部載入完畢,這在您的指令碼依賴於 DOM 存在時很有用(例如,它們修改頁面上的一個或多個元素)。
總結
async和defer都指示瀏覽器在單獨的執行緒中下載指令碼,而頁面的其餘部分(DOM 等)正在下載,因此在獲取過程中頁面載入不會被阻塞。- 帶有
async屬性的指令碼將在下載完成後立即執行。這會阻塞頁面並且不保證任何特定的執行順序。 - 帶有
defer屬性的指令碼將按照它們在頁面中的順序載入,並且只有在所有內容都載入完成後才會執行。 - 如果您的指令碼應該立即執行並且沒有任何依賴關係,那麼請使用
async。 - 如果您的指令碼需要等待解析並依賴於其他指令碼和/或 DOM 的存在,請使用
defer載入它們,並將它們相應的<script>元素按照您希望瀏覽器執行它們的順序放置。
模組回退
支援 type 屬性的 module 值的瀏覽器會忽略任何帶有 nomodule 屬性的指令碼。這使您能夠使用模組指令碼,同時為不支援的瀏覽器提供標記為 nomodule 的回退指令碼。
<script type="module" src="main.js"></script>
<script nomodule src="fallback.js"></script>
使用 importmap 匯入模組
在指令碼中匯入模組時,如果您不使用 type=importmap 功能,那麼每個模組都必須使用絕對或相對 URL 的模組說明符進行匯入。在下面的示例中,第一個模組說明符是絕對 URL,而第二個("./shapes/square.js")相對於文件的基本 URL 進行解析。
import { name as circleName } from "https://example.com/shapes/circle.js";
import { name as squareName, draw } from "./shapes/square.js";
匯入對映允許您提供一個對映,如果匹配,可以替換模組說明符中的文字。下面的匯入對映定義了鍵 circle 和 square,它們可以作為上面顯示的模組說明符的別名。
<script type="importmap">
{
"imports": {
"circle": "https://example.com/shapes/circle.js",
"square": "./shapes/square.js"
}
}
</script>
這允許我們使用模組說明符中的名稱(而不是絕對或相對 URL)匯入模組。
import { name as circleName } from "circle";
import { name as squareName, draw } from "square";
有關匯入對映功能的更多示例,請參閱 JavaScript 模組指南中的使用匯入對映匯入模組部分。
在 HTML 中嵌入資料
您還可以透過在 type 屬性中指定有效的非 JavaScript MIME 型別,使用 <script> 元素透過伺服器端渲染將資料嵌入 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 令牌;頁面的渲染將被阻塞,直到指令碼被獲取和執行。在下面的示例中,我們阻塞了一個非同步指令碼的渲染,這樣指令碼就不會阻塞解析,但保證在渲染開始之前被評估。
<script blocking="render" async src="async-script.js"></script>
技術摘要
規範
| 規範 |
|---|
| HTML # 指令碼元素 |
瀏覽器相容性
載入中…