<script>: 脚本元素

基线 广泛可用

此功能已得到广泛认可,并在许多设备和浏览器版本中运行。它自 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 标头的值。

注意: 或者,可以通过发送包含 attributionReporting 选项的 fetch() 请求(直接在 fetch() 调用上设置或在传递到 fetch() 调用的 Request 对象上设置),或通过发送带有 XMLHttpRequest 来注册基于 JavaScript 的归因来源或触发器 setAttributionReporting() 在请求对象上调用。

您可以设置此属性的两个版本

  • 布尔值,即仅 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

blocking 实验性

此属性明确指示在获取脚本时应阻止某些操作。要阻止的操作必须是下面列出的阻塞令牌的空格分隔列表。

  • render:阻止屏幕上内容的渲染。
crossorigin

普通 script 元素会将最少的信息传递给 window.onerror,用于未通过标准 CORS 检查的脚本。要允许对使用单独域进行静态媒体的网站进行错误记录,请使用此属性。有关其有效参数的更详细说明,请参阅CORS 设置属性

defer

此布尔属性设置为指示浏览器该脚本旨在在文档解析完毕后但在触发 DOMContentLoaded 事件之前执行。

具有 defer 属性的脚本将阻止 DOMContentLoaded 事件触发,直到脚本加载并完成评估。

警告: 如果src 属性不存在(即对于内联脚本),则不应使用此属性,在这种情况下它将不起作用。

defer 属性对模块脚本 没有影响——它们默认推迟。

具有 defer 属性的脚本将按其在文档中出现的顺序执行。

此属性允许消除解析器阻塞的 JavaScript,在该情况下,浏览器必须加载并评估脚本才能继续解析。async 在这种情况下具有类似的效果。

如果该属性与async 属性一起指定,则该元素的行为将如同仅指定了async 属性。

fetchpriority

提供获取外部脚本时要使用的相对优先级的提示。允许的值

high

相对于其他外部脚本发出高优先级获取信号。

low

相对于其他外部脚本发出低优先级获取信号。

auto

默认值:发出相对于其他外部脚本的自动确定获取优先级的信号。

integrity

此属性包含用户代理可以用来验证获取的资源是否已在未进行意外操作的情况下传递的内联元数据。当 src 属性未指定时,该属性不得指定。请参阅子资源完整性

nomodule

此布尔属性设置为指示在支持ES 模块的浏览器中不应执行该脚本——实际上,这可用于为不支持模块化 JavaScript 代码的旧版浏览器提供后备脚本。

nonce

密码 nonce(一次性使用的数字)允许 script-src 内容安全策略 中的脚本。服务器必须在每次传输策略时生成一个唯一的 nonce 值。提供一个无法猜测的 nonce 非常重要,因为否则绕过资源策略将微不足道。

referrerpolicy

指示在获取脚本或脚本获取的资源时要发送哪个引用者

  • no-referrer:不会发送 Referer 标头。
  • no-referrer-when-downgrade:不会将 Referer 标头发送到没有 TLSHTTPS)的来源
  • 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 模块。脚本内容的处理被推迟。charsetdefer 属性没有效果。有关使用 module 的信息,请参阅我们的JavaScript 模块 指南。与经典脚本不同,模块脚本需要使用 CORS 协议进行跨来源获取。

speculationrules 实验性

此值指示元素的主体包含推测规则。推测规则采用 JSON 对象的形式,该对象确定浏览器应预取或预渲染哪些资源。这是推测规则 API 的一部分。

任何其他值

嵌入的内容被视为数据块,并且浏览器不会处理。开发人员必须使用不是 JavaScript MIME 类型的有效 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 的模块说明符导入。在下面的示例中,第一个模块说明符("./shapes/square.js")相对于文档的基本 URL 解析,而第二个是绝对 URL。

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

导入映射允许您提供一个映射,如果匹配,可以替换模块说明符中的文本。下面的导入映射定义了键 squarecircle,它们可以作为上面显示的模块说明符的别名。

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

这使我们能够使用模块说明符中的名称(而不是绝对或相对 URL)导入模块。

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

有关使用导入映射可以执行的操作的更多示例,请参阅 JavaScript 模块指南中的 使用导入映射导入模块 部分。

在 HTML 中嵌入数据

您还可以使用 <script> 元素通过在 type 属性中指定有效的非 JavaScript MIME 类型来在具有服务器端渲染的 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 标准
# the-script-element

浏览器兼容性

BCD 表格仅在启用 JavaScript 的浏览器中加载。

另请参见