Как переопределить Content-Type / charset, указанный в заголовке HTTP, используя HTML / CSS / JS - PullRequest
0 голосов
/ 20 октября 2019

Тестовый пример

У меня есть живой тестовый пример, доступный здесь: 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. Это наш интересный байт. Это ISO-8859-1 представление знак авторского права . Обратите внимание, что это кодированный символ ISO-8859-1, а не UTF-8. Если бы он был в кодировке UTF-8, байты были бы c2 a9.

META Tag

Чтобы гарантировать, что содержимое этого HTML-файла интерпретируется как данные в кодировке ISO-8859-1в HTML-коде есть тег <meta>:

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

Local Behavior

Если вы откроете этот файл в своей системе локально с помощью браузера, вы, скорее всего, увидите выводнапример:

enter image description here

Это ожидается, потому что при локальном открытии файла HTTP-сервер не отправляет заголовки HTTP. Таким образом, кодировка iso-8859-1, указанная в теге <meta>, соблюдается.

GitHub Behavior

Если вы обращаетесь к URL https://lonelearner.github.io/charset-issue/index.html с помощью браузера, вы, скорее всего, увидитетакой вывод:

enter image description here

Это также ожидается. Если вы заметили, что страница обслуживается GitHub Pages, и сервер GitHub Pages всегда возвращает заголовок HTTP, который задает кодировку ISO-8859-1.

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

Поскольку заголовок HTTP указывает кодировку символов, кодировка символов в <meta> тег больше не учитывается.

Вопрос

Можно ли в любом случае переопределить кодировку символов, указанную в заголовке HTTP, с помощью HTML, JavaScript или CSS, чтобы сообщить браузеру, что этот контент следует интерпретировать? в качестве кодировки ISO-8859-1, даже если в заголовке HTTP указано иное?

Я знаю, что всегда могу записать символ авторского права как &copy; или кодировать символ в UTF-8 в файле, но давайте рассмотримтакие решения выходят за рамки этого вопроса, потому что есть ограничения, с которыми я имею дело:

  • Содержимое <body> предоставляется мне в виде текста в кодировке ISO-8859-1.
  • Я не могу изменить содержимое <body>. Я должен использовать кодированный в стандарте ISO-8859-1 текст в моем HTML.
  • Я могу изменить что угодно в теге <head>. Поэтому я могу добавить JavaScript, CSS или любые другие приемы, которые могут решить эту проблему.

1 Ответ

1 голос
/ 22 октября 2019

Можно ли в любом случае переопределить кодировку символов, указанную в заголовке HTTP, с помощью HTML, JavaScript или CSS, чтобы сообщить браузеру, что этот контент следует интерпретировать как кодировку ISO-8859-1, даже если в заголовке HTTP указано иное?

Нет. Заголовок HTTP является достовернымкодировка символов уже объявлена ​​в заголовке HTTP. Если это так, необходимо задать метаэлемент для объявления той же кодировки. "

...