Ответ 1
Этот текст ввода часто содержит символы, которые являются неправильными для выходной кодировки, такие вещи, как "умные кавычки", которые поступают из документа в кодировке Windows-1252
"Умные кавычки" (байты 147 и 148 в cp1252) являются вполне допустимыми символами Unicode, 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" />
в <head> .
Можно ли просто установить атрибут accept-charset в форме и сделать браузер для меня?
Нет, accept-charset в основном бесполезен благодаря IE, который неправильно понимает, что это означает "попробуйте использовать эту кодировку, если тот, который на странице не может кодировать символы, которые мы хотим", вместо "всегда используйте эту кодировку". Это означает, что если вы используете accept-charset, вы можете получить смесь кодировок, представленных сразу, без возможности выяснить, что именно. Ницца!
Как моя база данных принимает эти символы, которые являются зарезервированными/управляющими символами в UTF-8?
В MySQL UTF-8 - это просто сортировка, используемая для сравнения и упорядочения. Он по-прежнему хранит данные в виде байтов, и их не волнует, если они не являются допустимыми последовательностями UTF-8.
В любом случае рекомендуется декодировать и проверять входящие последовательности UTF-8 в вашем приложении, поскольку "короткие последовательности", недействительные в современном Unicode, могут скрыть "< который по-прежнему будет распознаваться старыми браузерами (по крайней мере, IE6 до SP2, Opera 7).
ETA:
Итак, я ввел строку, содержащую байт 146
Нет, вы ввели символ Unicode U + 201B. Браузер имеет дело с символами Unicode, а не с байтами, вплоть до момента, когда он должен отправить сериализованную форму на сервер. Затем он решает, как превратить символы в байты, и если страница обрабатывается как UTF-8, она всегда будет выбирать UTF-8.
(Если это не UTF-8, браузеры, как правило, обманывают нестандартным образом: для всех символов, которые не могут вписываться в кодировку, они будут кодировать их к символам HTML-символов, например '& # 8217;. Это неправильно, потому что теперь вы не можете отличить между экранированным браузером & и реальным, введенным пользователем символом &, и это коварно неправильно, потому что если вы затем эхом ссылаетесь как неэкранированный HTML, он выглядит как будто вы все правильно поняли, что на самом деле вы просто сделали большую старую дыру в безопасности.)
Он попал в базу данных как 146
Действительно, '\ x92 байт, а не'\xC2\x92, '\ xE2\x80\x99 или' & # 146;?
это получилось, когда я выпустил XML (кодированный UTF-8), как 146. Никаких жалоб в браузере
Тогда он не появился как один 146-байтовый. Браузер будет жаловаться, если в файле XML будет указано "\ x92". (Не HTML файл, в котором недопустимые последовательности UTF-8 выходят в виде символа пропавшего символа.)
Я подозреваю, что он выходит как '& # 146; символьная ссылка, которая хорошо сформирована (хотя символ U + 0092 является частью набора управления C1, поэтому не будет отображаться как что-либо полезное). Если это то, что происходит, ваша страница формы не подбирается как UTF-8 в конце концов, и вы страдаете от проблемы с браузером-автоматическим экранированием, описанной выше.