Декодирование умлаутов в URL (или составное или предварительно составленное кодирование)
Мое приложение обрабатывает URL-адреса.
Один пример ниже:
https://127.0.0.1/Datei_Verz._Änderung.gif
Что посылает браузер:
https://127.0.0.1/Datei_Verz._%C3%84nderung.gif
Когда это не экранировано (с помощью AtlUnescapeUrl),% C3 и% 84 видятся как отдельные символы, и поэтому я получаю:
https://127.0.0.1/Datei_Verz._Ã „nderung.gif
Таким образом, unescape не распознает, что браузер отправил составной символ, а не предварительно составленный (используя объяснение из MSDN).
В идеале браузер должен был бы представлять Ä одной кодовой точкой Юникода LATIN CAPITAL LETTER A WITH DIAERESIS (U+00C4), которая, как я полагаю, могла быть%00C4 в URL.
Так как же декодировать начальный URL?
1 ответ
Это не связано с нормализацией Unicode (предварительно составленные символы против разложенных последовательностей символов). Это просто случай неправильной байтовой кодировки.
В идеале браузер должен был бы представлять Ä одной кодовой точкой Юникода LATIN CAPITAL LETTER A WITH DIAERESIS (U+00C4), которая, как я полагаю, могла быть%00C4 в URL.
Нет: URL-кодировка является байтовой кодировкой; %-экраны строго две цифры (один байт), так %00C4
будет нулевой байт, за которым следуют буквенные символы C4
,
Не существует% -кодирования, которое покрывает одну кодовую точку одной escape-последовательностью. Компоненты URL Unicode должны быть закодированы в байтах, прежде чем быть экранированными в %nn
последовательности.
%C4
будет кодировка для Ä
для веб-приложения, основанного на стандарте ISO-8859-1 или кодовой странице 1252, но кодирование, которое большинство веб-приложений используют сегодня (и которое предписано стандартом IRI), - UTF-8. %C3%84
правильная кодировка Ä
в UTF-8.
К сожалению, ATL - это печальная старая библиотека, существовавшая до появления IRI. Когда он видит escape-последовательности не-ASCII, он декодирует их в Unicode, используя кодовую страницу по умолчанию (ANSI) вашего компьютера, которая никогда не является UTF-8. Для западноевропейской установки Windows вы получаете кодовую страницу 1252, в которой %C3%84
означает два символа Ä
,
(Возможно, это ошибка. В версии atlutil.h, которую я должен передать, есть предыдущий комментарий, в котором говорится, что не имеет значения, какая кодировка используется, потому что нет символов, отличных от ASCII, что верно для кода в AtlEscapeUrl
выше, это небрежно скопировано с, но не совсем верно для AtlUnescapeUrl
, Казалось бы, это означает, что функции escape и unescape в ATL не используют одни и те же кодировки и, следовательно, не используют обходные пути... упс.)
Чтобы обойти эту проблему, вы можете сделать биты Unicode самостоятельно. Вместо вызова версии Unicode (LPWSTR) AtlUnescapeUrl
преобразовать входную строку Unicode в байтовую строку, используя кодировку UTF-8 (MultiByteToWideChar
CP_UTF8), затем вызовите байтовую (LPSTR) версию AtlUnescapeUrl
на строку байтов, и декодировать снова (WideCharToMultiByte
CP_UTF8).
Или же выберите другую, менее разрушенную библиотеку для обработки URL.