<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 的浏览器中加载。