Декодирование умлаутов в 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.

Другие вопросы по тегам