Как определить, закодирована ли строка с помощью escape() или encodeURIComponent()

У меня есть веб-служба, которая получает данные от разных клиентов. Некоторые из них отправляют данные, закодированные с помощью escape(), в то время как другие вместо этого используют encodeURIComponent(). Есть ли способ определить кодировку, используемую для экранирования данных?


person Rodrigo    schedule 14.08.2009    source источник
comment
У меня нет контроля над данными, отправляемыми нашими клиентами, и, как я уже говорил, некоторые из них используют escape(), а другие вместо этого используют encodeURIComponent(). Использование unescape в строке, закодированной с помощью encodeURIComponent(), генерирует неверные символы, и я хочу этого избежать. Является ли юридическая проверка, чтобы посмотреть, есть ли в строке только escape-последовательности в парах, как %xx%xx.   -  person Rodrigo    schedule 14.08.2009
comment
Наконец я нашел ответ. decodeURIComponent всегда будет декодировать экранированные символы, поскольку он использует некоторые соглашения для определения для каждого символа, кодируется ли он в utf-8 или ascii. Однако, как отмечает Swingley, если клиент отправляет данные, закодированные с помощью escape(), некоторые данные могут быть потеряны или искажены. Поэтому я даю ему точку.   -  person Rodrigo    schedule 02.09.2009
comment
Поскольку encodeURIComponent() использует кодировку символов UTF-8 ›= 128, вы можете на стороне сервера проверить допустимые последовательности UTF-8. Если данные содержат недопустимые последовательности UTF-8, данные были созданы с помощью escape(), и вам, вероятно, придется предположить, что они закодированы в соответствии со стандартом ISO-8859-1. Октеты данных ISO-8859-1 на практике никогда не выглядят как действительные последовательности UTF-8.   -  person krisku    schedule 09.08.2016


Ответы (5)



Это не поможет на стороне сервера, но на стороне клиента я использовал исключения javascript, чтобы определить, является ли кодировка URL-адреса кодировкой ISO Latin или UTF8.

decodeURIComponent создает исключение для недопустимых последовательностей UTF8.

try {
     result = decodeURIComponent(string);
}
catch (e) {
     result =  unescape(string);                                       
}

Например, умляут 'ä' %E4 в кодировке ISO Latin вызовет исключение в Firefox, а кодировка 'ä' %C3%A4 в кодировке UTF8 - нет.

Смотрите также

person mika    schedule 25.11.2011

Я понимаю, что это старый вопрос, но я не знаю лучшего решения. Итак, я делаю это так (благодаря комментарию Роберта Питта выше):

function isEncoded(str) {
    return typeof str == "string" && decodeURIComponent(str) !== str;
}

Я еще не сталкивался со случаем, когда это не удалось. Что не означает, что такого случая не существует. Может быть, кто-то может пролить свет на это.

person Dejan Janjušević    schedule 13.05.2015
comment
Это не удастся, если что-то закодировано лишь частично, например http://google.de/hello%20world woops. Все еще нужно найти элегантный способ справиться с этим. - person maryisdead; 24.06.2016
comment
Это решение не имеет абсолютно никакого отношения к попытке определить, какой из escape() или encodeURIComponent() что-то было закодировано. - person krisku; 09.08.2016

Спасибо @mika за отличный ответ. Возможно, только одно улучшение, поскольку функция unescape считается устаревшей:

declare function unescape(s: string): string;


decodeURItoString(str): string {

 var resp = str;

 try {
    resp = decodeURI(str);
 } catch (e) {
    console.log('ERROR: Can not decodeURI string!');

    if ( (unescape != null) && (unescape instanceof Function) ) {
        resp = unescape(str);
    }
 }

return resp;

}

person Dudi    schedule 17.08.2017

Вам не нужно различать их. escape() - это так называемое процентное кодирование, оно отличается от кодирования URI только тем, как кодируются определенные символы. Например, пробел закодирован как %20 с escape-кодом, но + с кодировкой URI. После декодирования вы всегда получаете одно и то же значение.

person ZZ Coder    schedule 14.08.2009
comment
Они сильно различаются тем, как кодируются не-ascii-символы: encodeURIComponent() создает последовательности, закодированные в процентах UTF-8, а escape() процентно кодирует октеты (как в байтах ISO-8859-1). - person krisku; 09.08.2016