<script>: 指令碼元素
<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標頭的值。注意: 或者,可以透過傳送包含
attributionReporting選項的fetch()請求(直接在fetch()呼叫上設定或在傳遞到fetch()呼叫的Request物件上設定),或透過傳送帶有XMLHttpRequest來註冊基於 JavaScript 的歸因來源或觸發器setAttributionReporting()在請求物件上呼叫。您可以設定此屬性的兩個版本
- 布林值,即僅
attributionsrc名稱。這指定您希望將Attribution-Reporting-Eligible標頭髮送到與src屬性指向的相同伺服器。當您在同一伺服器上處理歸因來源或觸發器註冊時,這很好。註冊歸因觸發器時,此屬性是可選的,如果省略,將使用空字串值。 - 包含一個或多個 URL 的值,例如這在請求的資源不在您控制的伺服器上,或者您只是想在不同的伺服器上處理註冊歸因來源的情況下很有用。在這種情況下,您可以指定一個或多個 URL 作為html
<script src="myscript.js" attributionsrc="https://a.example/register-source https://b.example/register-source"></script>attributionsrc的值。當資源請求發生時,Attribution-Reporting-Eligible標頭將被髮送到在attributionSrc中指定的 URL(除資源來源外)。然後,這些 URL 可以響應Attribution-Reporting-Register-Source或Attribution-Reporting-Register-Trigger標頭,以完成註冊。注意: 指定多個 URL 意味著可以在同一個功能上註冊多個歸因來源。例如,您可能擁有不同的廣告系列,您試圖衡量其成功率,這涉及生成不同資料上的不同報告。
有關更多詳細資訊,請參閱歸因報告 API。
- 布林值,即僅
blocking實驗性-
此屬性明確指示在獲取指令碼時應阻止某些操作。要阻止的操作必須是下面列出的阻塞令牌的空格分隔列表。
render:阻止螢幕上內容的渲染。
crossorigin-
普通
script元素會將最少的資訊傳遞給window.onerror,用於未透過標準 CORS 檢查的指令碼。要允許對使用單獨域進行靜態媒體的網站進行錯誤記錄,請使用此屬性。有關其有效引數的更詳細說明,請參閱CORS 設定屬性。 defer-
此布林屬性設定為指示瀏覽器該指令碼旨在在文件解析完畢後但在觸發
DOMContentLoaded事件之前執行。具有
defer屬性的指令碼將阻止DOMContentLoaded事件觸發,直到指令碼載入並完成評估。警告: 如果
src屬性不存在(即對於內聯指令碼),則不應使用此屬性,在這種情況下它將不起作用。defer屬性對模組指令碼 沒有影響——它們預設推遲。具有
defer屬性的指令碼將按其在文件中出現的順序執行。此屬性允許消除解析器阻塞的 JavaScript,在該情況下,瀏覽器必須載入並評估指令碼才能繼續解析。
async在這種情況下具有類似的效果。如果該屬性與
async屬性一起指定,則該元素的行為將如同僅指定了async屬性。 fetchpriority-
提供獲取外部指令碼時要使用的相對優先順序的提示。允許的值
integrity-
此屬性包含使用者代理可以用來驗證獲取的資源是否已在未進行意外操作的情況下傳遞的內聯元資料。當
src屬性未指定時,該屬性不得指定。請參閱子資源完整性。 nomodule-
此布林屬性設定為指示在支援ES 模組的瀏覽器中不應執行該指令碼——實際上,這可用於為不支援模組化 JavaScript 程式碼的舊版瀏覽器提供後備指令碼。
nonce-
密碼 nonce(一次性使用的數字)允許 script-src 內容安全策略 中的指令碼。伺服器必須在每次傳輸策略時生成一個唯一的 nonce 值。提供一個無法猜測的 nonce 非常重要,因為否則繞過資源策略將微不足道。
referrerpolicy-
指示在獲取指令碼或指令碼獲取的資源時要傳送哪個引用者
no-referrer:不會發送Referer標頭。no-referrer-when-downgrade:不會將Referer標頭髮送到沒有 TLS(HTTPS)的來源。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 模組 時如何解析模組說明符。
module-
此值使程式碼被視為 JavaScript 模組。指令碼內容的處理被推遲。
charset和defer屬性沒有效果。有關使用module的資訊,請參閱我們的JavaScript 模組 指南。與經典指令碼不同,模組指令碼需要使用 CORS 協議進行跨來源獲取。 speculationrules實驗性-
此值指示元素的主體包含推測規則。推測規則採用 JSON 物件的形式,該物件確定瀏覽器應預取或預渲染哪些資源。這是推測規則 API 的一部分。
- 任何其他值
-
嵌入的內容被視為資料塊,並且瀏覽器不會處理。開發人員必須使用不是 JavaScript MIME 型別的有效 MIME 型別來表示資料塊。所有其他屬性都將被忽略,包括
src屬性。
已棄用的屬性
備註
示例
基本用法
這些示例展示瞭如何使用 <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 的模組說明符匯入。在下面的示例中,第一個模組說明符("./shapes/square.js")相對於文件的基本 URL 解析,而第二個是絕對 URL。
import { name as squareName, draw } from "./shapes/square.js";
import { name as circleName } from "https://example.com/shapes/circle.js";
匯入對映允許您提供一個對映,如果匹配,可以替換模組說明符中的文字。下面的匯入對映定義了鍵 square 和 circle,它們可以作為上面顯示的模組說明符的別名。
<script type="importmap">
{
"imports": {
"square": "./shapes/square.js",
"circle": "https://example.com/shapes/circle.js"
}
}
</script>
這使我們能夠使用模組說明符中的名稱(而不是絕對或相對 URL)匯入模組。
import { name as squareName, draw } from "square";
import { name as circleName } from "circle";
有關使用匯入對映可以執行的操作的更多示例,請參閱 JavaScript 模組指南中的 使用匯入對映匯入模組 部分。
在 HTML 中嵌入資料
您還可以使用 <script> 元素透過在 type 屬性中指定有效的非 JavaScript MIME 型別來在具有伺服器端渲染的 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 標準 # the-script-element |
瀏覽器相容性
BCD 表格僅在啟用 JavaScript 的瀏覽器中載入。