Использование 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()