为什么我必须为我的 <script> 标签指定字符集属性?

Why must I specify charset attributes for my <script> tags?

我的情况有点奇怪:

  1. 主要 HTML 页面以 UTF-16 字符集提供(由于某些要求超出此问题的范围)
  2. HTML 页面使用 <script> 标签加载外部脚本(即它们具有 src 属性)
  3. 那些外部脚本在 US-ASCII/UTF-8
  4. Web 服务器正在提供内容类型为“application/javascript”且没有字符集提示的脚本
  5. 脚本没有字节顺序标记 (BOM)

加载上述页面时,Firefox 和 Chrome(当前版本)都会抛出错误,指出脚本文件的第一个字符无效。

查看相应开发工具视图的“网络”选项卡显示文件正常(它们在预览器中呈现正常)。

我的结论是,浏览器对“整个页面”的编码应该是什么或一些类似的愚蠢行为感到困惑。

所以我尝试将 charset="UTF-8" 属性添加到 <script> 标签,这似乎解决了问题。

但我真的不应该那样做,对吗?

首先,服务器会告诉客户端文档的类型。它是 application/javascript 并且没有指定字符集。 (实际上,RFC 表示 charset 仅适用于 text/* MIME 类型)。好的,我能理解为什么会有一些歧义。

但是文档类型是 javascript,对于如何处理您不知道其实际字符集的 javascript 文件,有一些明显的规则。例如,如果它有 BOM,则使用它。如果没有任何 BOM,应该很容易区分 UTF-16 和 UTF-8。 (请注意,在这些相同的页面上加载 CSS 文件似乎没有任何问题,这些文件也与脚本处于相同的情况。)

最后,封闭页面不必知道其依赖项的编码是什么。事实上,它可能不可能知道,并且显式指定charset然后将页面与其依赖项紧密耦合,反之亦然。

有没有办法让浏览器正确检测这些依赖项的字符集,而无需在页面本身中指定 charset

文件中没有 BOM,或者文件的 <script>Content-Type 中没有明确的 charset,文件的编码不明确。浏览器 可能 假定为 UTF-8(并且应该,根据 RFC 4329),但是如果脚本包含任何实际上未以 UTF-8 编码的非 ASCII 字符,则文件无法正确处理。

但是,HTML 5 第 4.11 节规定,如果 <script> 没有 charset 属性,则 <script> 的回退编码是文档的编码。如果没有 BOM 或 charset 指定文件的实际编码,则回退生效。

因此,请确保您的 HTML 和 JS 文件始终使用相同的编码,否则您必须以某种方式明确说明 JS 文件的 charset