【问题标题】:How to override Content-Type/charset specified in HTTP header using HTML/CSS/JS如何使用 HTML/CSS/JS 覆盖 HTTP 标头中指定的 Content-Type/charset
【发布时间】:2020-02-16 14:59:52
【问题描述】:

测试用例

我在这里有一个实时测试用例:https://lonelearner.github.io/charset-issue/index.html

由于 HTML 包含非 ASCII 字符,如果您想在您的系统上可靠地重现此测试用例,以下是重现它的方法。您可以使用以下任何一种方法来重现它:

  1. 从上面的 URL 获取页面。

    curl https://lonelearner.github.io/charset-issue/index.html -O
    
  2. 运行这个命令:

    echo "
    3c21444f43545950452068746d6c3e0a3c68746d6c3e0a20203c68656164
    3e0a202020203c7469746c653e636861727365742069737375653c2f7469
    746c653e0a202020203c6d65746120687474702d65717569763d22436f6e
    74656e742d547970652220636f6e74656e743d22746578742f68746d6c3b
    20636861727365743d69736f2d383835392d31223e0a20203c2f68656164
    3e0a20203c626f64793e0a202020203c703ea93c2f703e0a20203c2f626f
    64793e0a3c2f68746d6c3e0a
    " | xxd -p -r > index.html
    

有趣的字节

让我们看看我们在这个问题中关注的 ISO-8859-1 编码字符。

$ curl -s https://lonelearner.github.io/charset-issue/index.html | xxd -g1
00000000: 3c 21 44 4f 43 54 59 50 45 20 68 74 6d 6c 3e 0a  <!DOCTYPE html>.
00000010: 3c 68 74 6d 6c 3e 0a 20 20 3c 68 65 61 64 3e 0a  <html>.  <head>.
00000020: 20 20 20 20 3c 74 69 74 6c 65 3e 63 68 61 72 73      <title>chars
00000030: 65 74 20 69 73 73 75 65 3c 2f 74 69 74 6c 65 3e  et issue</title>
00000040: 0a 20 20 20 20 3c 6d 65 74 61 20 68 74 74 70 2d  .    <meta http-
00000050: 65 71 75 69 76 3d 22 43 6f 6e 74 65 6e 74 2d 54  equiv="Content-T
00000060: 79 70 65 22 20 63 6f 6e 74 65 6e 74 3d 22 74 65  ype" content="te
00000070: 78 74 2f 68 74 6d 6c 3b 20 63 68 61 72 73 65 74  xt/html; charset
00000080: 3d 69 73 6f 2d 38 38 35 39 2d 31 22 3e 0a 20 20  =iso-8859-1">.  
00000090: 3c 2f 68 65 61 64 3e 0a 20 20 3c 62 6f 64 79 3e  </head>.  <body>
000000a0: 0a 20 20 20 20 3c 70 3e a9 3c 2f 70 3e 0a 20 20  .    <p>.</p>.  
000000b0: 3c 2f 62 6f 64 79 3e 0a 3c 2f 68 74 6d 6c 3e 0a  </body>.</html>.

在最后一行之前的行(偏移量000000a0处的行),第9个字节是a9。那是我们有趣的字节。这是copyright sign 的 ISO-8859-1 表示。请注意,这是 ISO-8859-1 编码符号,而不是 UTF-8。如果它是 UTF-8 编码的,则字节将为c2 a9

元标记

为确保该 HTML 文件的内容被解释为 ISO-8859-1 编码数据,在 HTML 代码中有这个&lt;meta&gt; 标签:

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

本地行为

如果您使用浏览器在本地系统上打开此文件,您很可能会看到如下输出:

这是预期的,因为在本地打开文件时,没有 HTTP 服务器发送 HTTP 标头。因此,&lt;meta&gt; 标记中指定的iso-8859-1 编码被接受。

GitHub 行为

如果您使用浏览器访问 URL https://lonelearner.github.io/charset-issue/index.html,您很可能会看到如下输出:

这也是意料之中的。如果您注意到该页面使用 GitHub Pages 提供,并且 GitHub Pages 服务器始终返回指定 ISO-8859-1 编码的 HTTP 标头。

$ curl -sI https://lonelearner.github.io/charset-issue/index.html | grep -i content-type
content-type: text/html; charset=utf-8

由于 HTTP 标头指定了字符编码,&lt;meta&gt; 标签中的字符编码不再适用。

问题

我是否可以使用 HTML、JavaScript 或 CSS 覆盖 HTTP 标头中指定的字符编码,以告诉浏览器该内容应解释为 ISO-8859-1 编码,即使 HTTP 标头另有说明?

我知道我总是可以将版权符号写为 &amp;copy; 或在文件中以 UTF-8 编码符号,但让我们考虑这样的解决方案超出了这个问题的范围,因为这是我正在处理的限制与:

  • &lt;body&gt; 的内容以 ISO-8859-1 编码文本的形式提供给我。
  • 我无法修改&lt;body&gt; 的内容。我必须在我的 HTML 中使用 ISO-8859-1 编码的文本。
  • 我可以修改&lt;head&gt; 标签内的任何内容。所以我可以添加 JavaScript、CSS 或任何其他可以解决此问题的技巧。

【问题讨论】:

    标签: html utf-8 character-encoding http-headers iso-8859-1


    【解决方案1】:

    我是否可以使用 HTML、JavaScript 或 CSS 覆盖 HTTP 标头中指定的字符编码,以告诉浏览器该内容应解释为 ISO-8859-1 编码,即使 HTTP 标头另有说明?

    没有。 HTTP头是权威的w3

    "...HTTP 标头的优先级高于文档内元数据 声明,内容作者应始终考虑是否 字符编码已在 HTTP 标头中声明。如果它 即,必须将元元素设置为声明相同的编码。”

    【讨论】:

      猜你喜欢
      • 2011-09-07
      • 2015-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-19
      • 1970-01-01
      • 2016-01-30
      • 1970-01-01
      相关资源
      最近更新 更多