Тестовый пример
У меня есть живой тестовый пример, доступный здесь: https://lonelearner.github.io/charset-issue/index.html
Поскольку HTML содержит символы не ASCII, если вы хотите надежно воспроизвести этот тестовый пример в вашей системеВот как вы можете это воспроизвести. Вы можете использовать любой из этих методов для его воспроизведения:
Получить страницу сверху URL.
curl https://lonelearner.github.io/charset-issue/index.html -O
Запустите эту команду:
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
Если вы откроете этот файл в своей системе локально с помощью браузера, вы, скорее всего, увидите выводнапример:
Это ожидается, потому что при локальном открытии файла HTTP-сервер не отправляет заголовки HTTP. Таким образом, кодировка iso-8859-1
, указанная в теге <meta>
, соблюдается.
GitHub Behavior
Если вы обращаетесь к URL https://lonelearner.github.io/charset-issue/index.html с помощью браузера, вы, скорее всего, увидитетакой вывод:
Это также ожидается. Если вы заметили, что страница обслуживается 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 указано иное?
Я знаю, что всегда могу записать символ авторского права как ©
или кодировать символ в UTF-8 в файле, но давайте рассмотримтакие решения выходят за рамки этого вопроса, потому что есть ограничения, с которыми я имею дело:
- Содержимое
<body>
предоставляется мне в виде текста в кодировке ISO-8859-1. - Я не могу изменить содержимое
<body>
. Я должен использовать кодированный в стандарте ISO-8859-1 текст в моем HTML. - Я могу изменить что угодно в теге
<head>
. Поэтому я могу добавить JavaScript, CSS или любые другие приемы, которые могут решить эту проблему.