it-roy-ru.com

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

15
SeanPlusPlus

Привет!

Когда дело доходит до escape и unescape, я живу по двум правилам:

  1. Избегайте их, когда вы можете легко.
  2. В противном случае используйте их.

Избегать их, когда вы легко можете:

Как упоминалось в вопросе, и escape, и unescape устарели. В общем, следует избегать использования устаревших функций.

Итак, если encodeURIComponent или encodeURI справятся с задачей, вы должны использовать это вместо escape.

Использование их, когда вы не можете легко избежать их:

Браузеры, насколько это возможно, будут стремиться к достижению обратной совместимости. Все основные браузеры уже реализовали escape и unescape; почему они не выполняют их?

Браузеры должны будут переопределить escape и unescape, если новая спецификация требует от них этого. Но ждать! Люди, которые пишут спецификации, довольно умны. Они тоже заинтересованы в том, чтобы не сломать обратную совместимость!

Я понимаю, что приведенный выше аргумент слаб. Но поверьте мне ... когда дело доходит до браузеров, устаревшие вещи работают. Это даже включает устаревшие теги HTML, такие как <xmp> и <center>.

Использование escape и unescape:

Естественно, следующий вопрос: когда использовать escape или unescape?

Недавно, работая над CloudBrave , мне пришлось иметь дело с utf8, latin1 и взаимными конверсиями.

Прочитав кучу постов в блоге, я понял, насколько это просто:

var utf8_to_latin1 = function (s) {
    return unescape(encodeURIComponent(s));
};
var latin1_to_utf8 = function (s) {
    return decodeURIComponent(escape(s));
};

Эти взаимные преобразования, без использования escape и unescape, довольно сложны. Не избегая escape и unescape, жизнь становится проще.

Надеюсь это поможет.

15
Sumukh Barve

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()

1
Paolo