为什么我必须为我的 <script> 标签指定字符集属性?
Why must I specify charset attributes for my <script> tags?
我的情况有点奇怪:
- 主要 HTML 页面以 UTF-16 字符集提供(由于某些要求超出此问题的范围)
- HTML 页面使用
<script>
标签加载外部脚本(即它们具有 src
属性)
- 那些外部脚本在 US-ASCII/UTF-8
- Web 服务器正在提供内容类型为“application/javascript”且没有字符集提示的脚本
- 脚本没有字节顺序标记 (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
。
我的情况有点奇怪:
- 主要 HTML 页面以 UTF-16 字符集提供(由于某些要求超出此问题的范围)
- HTML 页面使用
<script>
标签加载外部脚本(即它们具有src
属性) - 那些外部脚本在 US-ASCII/UTF-8
- Web 服务器正在提供内容类型为“application/javascript”且没有字符集提示的脚本
- 脚本没有字节顺序标记 (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
。