如何在单独的JS文件中声明字符编码?

17
我们可以通过下面的代码在单独的CSS文件中声明字符编码:

@charset "UTF-8";

我的问题是:
如何在单独的JS文件中声明字符编码?
如果我把一个JS文件发送给我的朋友,我希望他(她)可以从代码中看出这个JS文件的字符编码,在他(她)开始浏览或编辑这个JS文件时。
谢谢!
3个回答

14
你无法直接定义文件的字符集。但是,你可以在将文件引入页面的script标签中使用charset属性来定义它。这必须与你提供文件的Content-Type中的字符集(如果有)匹配。引用如下:

charset 属性指定外部脚本资源的字符编码。如果没有 src 属性,则不能指定该属性。如果设置了该属性,则其值必须是有效的字符编码名称,必须与该编码的 首选 MIME 名称 匹配(ASCII 不区分大小写),并且必须与外部文件的 Content-Type 元数据 中给出的 charset 参数所指定的编码匹配(如果有的话)。[IANACHARSET]

关于您的编辑:

如果我把一个 JS 文件发送给我的朋友,我希望他(她)可以从代码本身中了解这个 JS 文件的字符编码,当他(她)开始浏览或编辑这个 JS 文件时。

为此,你需要直接告诉他/她。如果文件是UTF-8、Windows-1252或ISO 8859-1编码,不幸的是文件中没有编码指示器可用,因此我建议在开头加上类似于以下的注释:

// Encoding: UTF-8

如果您使用UTF-16或UTF-32,您应该能够告诉您的编辑器使用BOM,其他Unicode-aware编辑器应该可以看到并理解它。这通常只适用于在需要大量多字节字符的文本(语言)中编写注释,并且如果注释与代码的比例很高(因为代码是用西方文本编写的)。当然,您可以使用任何编码方式。只是如果注释与代码的比例较低,则最好坚持使用UTF-8,即使注释是在需要大量四字节字符的文本中,因为代码每个字符只需要一个字节。(而在UTF-16中,您可能会在注释中有更多的双字节而不是四字节字符,但代码始终需要每个字符两个字节;在UTF-32中,每个字符需要四个字节。因此,整个文件可能会更大,即使注释占用的空间较小。但是,如果我猜测您提出问题的原因,我可能已经告诉您比我更好了。)

1
您还可以为UTF-8包含BOM,浏览器会予以尊重。 - Andrea
@Andrea:并非所有浏览器都能可靠地解析。设置响应的“字符集”不是可选项,相关的RFC非常明确地指出,如果没有字符集,则响应为US-ASCII。就在几周前,这里有一个关于此问题的提问,IE在UTF-8中解析ajax请求的JSON,但Firefox却因BOM而失败,称其为无效的JSON。 - T.J. Crowder
@T.J.Crowder 相关的 RFC 是哪个?WHATWG 的编码规范指出,“字节顺序标记(也称为 BOM)比任何其他东西都更具权威性”。当然,如果您正确地处理事情,应该包括 charset=。 - Andrea
@Andrea:WHAT-WG的规范不是RFC。无论如何,我们可以得出以下结论:1. BOM不能被可靠地识别,2. 使用“charset”。让我们停止混淆视听,好吗?特别是,我建议删除上面误导性的评论,即浏览器会可靠地识别BOM:它们并不总是这样做。 - T.J. Crowder

3
如果您想以人类可读的方式指示文件的编码方式,可以采用T.J. Crowder的方法(在文件中添加注释,如// Encoding: UTF-8)。正如Jukka K. Korpela所指出的,您也可以使用BOM。
但是,如果您想以机器可读的方式指示在文档中声明的字符集,还有其他几种方法:
例如,在Apache httpd服务器上,您可以使用以下任何一个声明:
  1. AddDefaultCharset UTF-8
  2. AddCharset UTF-8 .js
  3. AddType 'application/javascript; charset=UTF-8' js*

* 我不想为使用"application/javascript"而辩护,而不是"text/javascript"。但是,如果您想知道哪个更好一些,可以参考https://dev59.com/wW855IYBdhLWcg3w3Ibs#4101763。但是,考虑到主题,application/javascript似乎非常合适(特别是如果您打算使用BOM,因为它表示应将代码视为二进制)。

如果代码将在服务器端解释/处理/编译(例如PHP),您可以在文档中设置标题,例如……

header("Content-Type: application/javascript; charset=utf-8");

至少在PHP中,请确保在任何输出之前添加标题语句。

最后,在确定要使用哪个声明时,请考虑(在IE中理解/遵守,即不在IE中)BOM比文档标头具有更高的权威性。而且两者都优先于链接/源字符集声明(如<script type="application/javascript" src="script.js" charset="utf-8"></script>)。

看起来你不应该再使用application/javascript或添加charset参数,而是直接使用text/javascript:https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#textjavascript。如果你的文档字符集已经是UTF-8,那么就不需要额外的东西了:https://html.spec.whatwg.org/multipage/obsolete.html#attr-script-charset。 - Ronald

3

在 JavaScript 中,没有像 CSS 一样在文件本身中声明编码的构造。在传送数据时应将编码通知接收者。当将文件作为电子邮件附件发送时,您的电子邮件程序可能包含指示编码的 Content-Type 标头,也可能难以确定编码。

在 UTF-8 编码的文件开头也可以放置字节顺序标记 (BOM)。虽然 UTF-8 中不存在字节顺序问题,但 BOM 可作为一个有用的指示器 - 以 BOM 形式开头的文件很可能是 UTF-8 编码。因此,在缺乏其他指示的情况下,程序可能会推断出编码。当然,这并不是 100% 可靠,但还是非常有用的。

许多文本编辑器都提供“保存为带有 BOM 的 UTF-8 编码”选项。

(在网页上,BOM 曾经被认为是一种风险,因为浏览器被观察到将其视为字符数据。现在,即使在 UTF-8 中,BOM 也是有用而不是风险。)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接