Использование encodeURI() против escape() для строк utf-8 в JavaScript
Я обрабатываю строки utf-8 в JavaScript и должен избегать их.
Оба escape()/unescape() и encodeURI()/decodeURI() работают в моем браузере.
побег()
> var hello = "안녕하세요"
> var hello_escaped = escape(hello)
> hello_escaped
"%uC548%uB155%uD558%uC138%uC694"
> var hello_unescaped = unescape(hello_escaped)
> hello_unescaped
"안녕하세요"
encodeURI()
> var hello = "안녕하세요"
> var hello_encoded = encodeURI(hello)
> hello_encoded
"%EC%95%88%EB%85%95%ED%95%98%EC%84%B8%EC%9A%94"
> var hello_decoded = decodeURI(hello_encoded)
> hello_decoded
"안녕하세요"
Однако Mozilla говорит, что escape() устарел.
Хотя encodeURI() и decodeURI() работают с указанной выше строкой utf-8, документы (а также имена функций сами) говорят мне, что эти методы предназначены для URI; Я не вижу нигде utf-8 нигде.
Проще говоря, можно ли использовать encodeURI() и decodeURI() для строк utf-8?
Ответы
Ответ 1
Привет!
Когда дело доходит до escape
и unescape
, я живу по двум правилам:
- Избегайте их, когда вы легко можете.
- В противном случае используйте их.
Избегайте их, когда вы легко можете:
Как упоминалось в вопросе, обе escape
и unescape
устарели. В общем, следует избегать использования устаревших функций.
Итак, если encodeURIComponent
или encodeURI
делает трюк для вас, вы должны использовать это вместо escape
.
Использование их, когда вы не можете легко избежать их:
Браузеры будут, насколько это возможно, стремиться к обратной совместимости. Все основные браузеры уже реализованы escape
и unescape
; почему бы им не реализовать их?
Браузеры должны были бы переопределить escape
и unescape
, если новая спецификация требует от них этого. Но ждать! Люди, которые пишут спецификации, довольно умны. Они тоже заинтересованы в том, чтобы не нарушать обратную совместимость!
Я понимаю, что приведенный выше аргумент слабый. Но поверьте мне, когда дело доходит до браузеров, устаревшие вещи работают. Это даже включает устаревшие HTML-теги, такие как <xmp>
и <center>
.
Использование escape
и unescape
:
Итак, следующий вопрос: когда можно использовать escape
или unescape
?
Недавно, работая над CloudBrave, мне пришлось иметь дело с utf8
, latin1
и inter-conversion.
Прочитав кучу сообщений в блоге, я понял, насколько это просто:
var utf8_to_latin1 = function (s) {
return unescape(encodeURIComponent(s));
};
var latin1_to_utf8 = function (s) {
return decodeURIComponent(escape(s));
};
Эти межконверсии, без использования escape
и unescape
, скорее задействованы. Не избегая escape
и unescape
, жизнь становится проще.
Надеюсь, что это поможет.
Ответ 2
Mozilla говорит, что escape() устарел.
Да, вы должны избегать как escape()
, так и unescape()
Проще говоря, можно ли использовать encodeURI() и decodeURI() для строк utf-8?
Да, но в зависимости от формы ввода и необходимой формы вашего вывода вам может потребоваться дополнительная работа.
Из вашего вопроса я предполагаю, что у вас есть строка JavaScript, и вы хотите преобразовать кодировку в UTF-8 и, наконец, сохранить строку в некоторой экранированной форме.
Прежде всего важно отметить, что строки JavaScript, поддерживающие UCS-2, похожи на UTF-16, отличные от UTF-8.
Смотрите: https://mathiasbynens.be/notes/javascript-encoding
encodeURIComponent()
хорош для задания, превращая строку JavaScript UCS-2 в UTF-8 и вытесняет ее в виде последовательности подстрок %nn
, где каждая nn
- это две шестнадцатеричные цифры каждого байта.
Однако encodeURIComponent()
не пропускает буквы, цифры и несколько других символов в диапазоне ASCII. Но это легко исправить.
Например, если вы хотите превратить строку JavaScript в массив чисел, представляющий байты исходной строки, кодированной UTF-8, вы можете использовать эту функцию:
//
// Convert JavaScript UCS2 string to array of bytes representing the string UTF8 encoded
//
function StringUTF8AsBytesArrayFromString( s )
{
var i,
n,
u;
u = [];
s = encodeURIComponent( s );
n = s.length;
for( i = 0; i < n; i++ )
{
if( s.charAt( i ) == '%' )
{
u.push( parseInt( s.substring( i + 1, i + 3 ), 16 ) );
i += 2;
}
else
{
u.push( s.charCodeAt( i ) );
}
}
return u;
}
Если вы хотите повернуть строку в шестнадцатеричном представлении:
//
// Convert JavaScript UCS2 string to hex string representing the bytes of the string UTF8 encoded
//
function StringUTF8AsHexFromString( s )
{
var u,
i,
n,
s;
u = StringUTF8AsBytesArrayFromString( s );
n = u.length;
s = '';
for( i = 0; i < n; i++ )
{
s += ( u[ i ] < 16 ? '0' : '' ) + u[ i ].toString( 16 );
}
return s;
}
Если вы измените строку в цикле for на
s += '%' + ( u[ i ] < 16 ? '0' : '' ) + u[ i ].toString( 16 );
(добавление знака %
перед каждой шестнадцатеричной цифрой)
Полученная экранированная строка (кодированная UTF-8) может быть возвращена в строку JavaScript UCS-2 с decodeURIComponent()