Ассоциирование приложения с форматом Epub

В Mozilla MDN есть замечательная статья , которая описывает именно эту проблему:

«Проблема Unicode» Поскольку DOMStrings - это строки с 16-битным кодированием, в большинстве браузеры, вызывающие window.btoa в строке Unicode, вызывают исключение Character Out Of Range, если символ превышает диапазон 8-разрядного символа в кодировке ASCII. Существует два возможных способа решения этой проблемы:

  • первым из них является выход из всей строки, а затем ее кодирование,
  • , второй - преобразование UTF- 16 DOMString в массив символов UTF-8 и затем кодировать его.

Примечание к исходному ответу: ранее в статье MDN было предложено использовать unescape и escape для решения проблемы исключения Character Out Of Range, но с тех пор они устарели. Некоторые другие ответы здесь предложили обойти это с помощью decodeURIComponent и encodeURIComponent, это оказалось ненадежным и непредсказуемым.

В конце концов, вы определенно могли бы сэкономить некоторое горе с помощью библиотеки:

Вот текущая рекомендация, прямо из MDN, с некоторой дополнительной совместимостью TypeScript через @ MA-Maddin:

Кодирование UTF8 ⇢ base64

Реализовать регулярное выражение вместо устаревшей функции unescape

function b64EncodeUnicode(str) {
    return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) {
        return String.fromCharCode(parseInt(p1, 16))
    }))
}

b64EncodeUnicode('✓ à la mode') // "4pyTIMOgIGxhIG1vZGU="
b64EncodeUnicode('\n') // "Cg=="

Декодирование base64 ⇢ UTF8

В статье MDN изначально не был пример для декодирования, но теперь добавлено

function b64DecodeUnicode(str) {
    return decodeURIComponent(Array.prototype.map.call(atob(str), function(c) {
        return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)
    }).join(''))
}

b64DecodeUnicode('4pyTIMOgIGxhIG1vZGU=') // "✓ à la mode"
b64DecodeUnicode('Cg==') // "\n"

Исходное решение (устарело)

Это использовало escape и unescape (которые теперь устарели, хотя это все еще работает во всех современных браузерах):

function utf8_to_b64( str ) {
    return window.btoa(unescape(encodeURIComponent( str )));
}

function b64_to_utf8( str ) {
    return decodeURIComponent(escape(window.atob( str )));
}

// Usage:
utf8_to_b64('✓ à la mode'); // "4pyTIMOgIGxhIG1vZGU="
b64_to_utf8('4pyTIMOgIGxhIG1vZGU='); // "✓ à la mode"

И последнее: впервые я столкнулся с этой проблемой при вызове API GitHub. Чтобы заставить это работать на (Mobile) Safari должным образом, я фактически должен был удалить все пустое пространство от источника base64 до , я мог бы даже декодировать источник. Является ли это еще актуальным в 2017 году, я не знаю:

function b64_to_utf8( str ) {
    str = str.replace(/\s/g, '');    
    return decodeURIComponent(escape(window.atob( str )));
}

21
задан Jason 9 December 2014 в 16:08
поделиться