Последовательность %XX
в URI кодирует «октет», то есть восьмибитный байт.Это поднимает вопрос о том, к какому символу Unicode относится декодированный байт.Если моя память служит мне правильно, в более старых версиях спецификации URI не было точно определено, какая кодировка предполагается.В более поздних версиях спецификации URI было рекомендовано, чтобы UTF-8 был кодировкой кодировки по умолчанию.То есть, чтобы декодировать последовательность байтов, вы должны декодировать каждую последовательность %XX
и затем преобразовывать полученные байты в строку, используя набор символов UTF-8.
Это объясняет, почему %96
не будетдекодирования.Шестнадцатеричное значение 0x96 не является допустимой последовательностью UTF-8.Поскольку он находится за пределами ASCII, ему потребуется специальный байт модификатора перед тем, чтобы указать расширенный символ.(Подробнее см. В спецификации UTF-8.) Оба метода JavaScript encodeURIComponent()
и decodeURIComponent()
предполагают использование UTF-8 (как и должно быть), поэтому я не ожидал, что %96
будет правильно декодироваться.
Персонаж, на которого вы ссылались, это U + 2013, тире.Как, черт возьми, страница, на которую вы ссылаетесь, получает черту 0x96 (десятичное 150)?Они явно не предполагают кодировку UTF-8, которая является стандартом.Они не предполагают ASCII, который не содержит этот символ.Они даже не предполагают ISO-8859-1 , которая является стандартной кодировкой, которая использует один байт на символ.Оказывается, они используют специальную кодовую страницу Windows 1252 .То есть URI, который вы пытаетесь декодировать, предполагает, что пользователь находится на компьютере с Windows, а еще хуже - на компьютере с Windows на английском (или одном из нескольких других западных языков).
Короче говоря, таблица, которую вы используете, плохая.Он устарел и предполагает, что пользователь работает в английской системе Windows.Современный и правильный способ кодирования значений, отличных от ASCII, заключается в преобразовании их в UTF-8 и последующем кодировании каждого октета с использованием %XX
.Вот почему вы получили %E2%80%93
, когда пытались закодировать символ, и именно этого ожидает decodeURIComponent()
.Используемый вами URI неправильно закодирован.Если у вас нет другого выбора, вы можете догадаться, что URI использует Windows 1252, самостоятельно преобразовать байты, а затем использовать таблицу Windows 1252, чтобы узнать, какие значения Unicode были предназначены.Но это рискованно - откуда вы знаете, какой URI использует какую таблицу?Вот почему все остановились на UTF-8.Если возможно, скажите всем, кто дает вам эти URI, чтобы правильно их кодировать.