В этом вводимом тексте часто содержатся символы, неправильные для выходной кодировки, например «умные кавычки», полученные из документа в кодировке Windows-1252
«Умные кавычки» (байты 147 и 148 в cp1252) - это абсолютно допустимые символы Юникода, U + 201C и U + 201D. Ваше приложение должно быть способно обрабатывать их без проблем; если нет, вы делаете что-то не так, и, скорее всего, все символы, не входящие в ASCII, потерпят неудачу.
Независимо от того, были ли символы получены от того, кто их печатал или кто-то вставлял их из Word, браузер должен отправлять символы в кодировке UTF-8 в ваше приложение, которое должно хранить те же байты UTF-8 в базе данных.
Если браузер не отправляет в UTF-8, скорее всего, вы не можете установить кодировку HTML-страницы, содержащей форму. Это можно сделать с помощью:
Content-Type: text/html;charset=utf-8
HTTP-заголовок и / или:
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
элемент в .
Могу ли я просто установить атрибут accept-charset в форме и сделать так, чтобы браузер сделал это для меня?
Нет, accept-charset в принципе бесполезен благодаря IE, который неправильно интерпретирует его как «попробуйте использовать этот набор символов, если тот, что на странице не может кодировать нужные нам символы», вместо «всегда использовать этот набор символов». Это означает, что если вы используете accept-charset, вы можете получить сразу несколько кодировок, без возможности выяснить, что есть что. Nice!
почему моя база данных принимает эти символы, которые являются зарезервированными / управляющими символами в UTF-8?
В MySQL UTF-8 - это просто сопоставление, используемое для сравнения и упорядочения. Он по-прежнему хранит данные в байтах и не заботится о том, что они не являются действительными последовательностями UTF-8.
В любом случае, хорошая идея декодировать и проверять входящие последовательности UTF-8 в вашем приложении, потому что «короткие последовательности», недопустимые в современном Unicode, могут скрывать символ «<», который все еще будет распознаваться старыми браузерами (по крайней мере, IE6 pre-SP2, Opera 7). </p>
ETA:
Итак, я ввел строку, содержащую байт 146
Нет, вы ввели символ Unicode U + 201B. Браузер работает с символами Unicode, а не с байтами, вплоть до момента, когда он должен отправить сериализованную форму на сервер. Тогда он решает, как превратить символы в байты, и если страница обрабатывается как UTF-8, он всегда будет выбирать UTF-8.
(Если это не UTF-8, браузеры склонны к мошенничеству нестандартным способом: для всех символов, которые не могут поместиться в кодировке, он будет кодировать их в ссылки на символы HTML, такие как '' '. Это неправильно, потому что теперь вы не можете отличить экранированную браузером '&' от реальной, & типизированной пользователем '&', и это коварно неверно, потому что если вы затем отобразите ссылку в виде неэкранированного HTML, это будет похоже на вас ' правильно, что вы на самом деле только что сделали большую старую дыру в безопасности.)
Он вошел в базу данных как 146
Действительно, байт ‘\ x92’, а не ‘\ xC2 \ x92’, ‘\ xE2 \ x80 \ x99’ или ‘’ ’?
оно появилось, когда я создал XML (в кодировке UTF-8), как 146. Никаких жалоб из браузера
Тогда это не получилось как один 146 байт. Браузер будет жаловаться, когда ему дается given \ x92 ’в файле XML. (Не HTML-файл, в котором недопустимые последовательности UTF-8 выглядят как глиф отсутствующего символа.)
Я подозреваю, что он выходит как символьная ссылка ‘’, которая хорошо сформирована (хотя символ U + 0092 является частью набора элементов управления C1, поэтому не будет отображаться как что-либо полезное). Если это то, что происходит, ваша страница формы в конце концов не воспринимается как UTF-8, и вы столкнулись с проблемой браузера-авто-экранирования-отправки, описанной выше.