Я использую window.atob()
функцию Javascript для декодирования строки в кодировке base64 (в частности, содержимого в кодировке base64 из GitHub API). Проблема в том, что я возвращаю символы в кодировке ASCII (например, â¢
вместо ™
). Как я могу правильно обработать входящий поток в кодировке base64, чтобы он был декодирован как utf-8?
javascript
encoding
utf-8
брендонскрипт
источник
источник
atob
Ответы:
В документации Mozilla MDN есть отличная статья , которая описывает именно эту проблему:
Замечание о предыдущих решениях: статья MDN изначально предлагала использовать
unescape
иescape
для решенияCharacter Out Of Range
проблемы исключения, но с тех пор они устарели. В некоторых других ответах здесь предлагалось работать над этим,decodeURIComponent
иencodeURIComponent
это оказалось ненадежным и непредсказуемым. В самом последнем обновлении этого ответа используются современные функции JavaScript для повышения скорости и модернизации кода.Если вы пытаетесь сэкономить время, вы также можете рассмотреть возможность использования библиотеки:
Кодировка UTF8 ⇢ base64
Расшифровка base64 ⇢ UTF8
Решение, выпущенное до 2018 года (функциональное и, вероятно, лучшая поддержка старых браузеров, но не обновленное)
Вот текущая рекомендация, прямо из MDN, с некоторой дополнительной совместимостью с TypeScript через @ MA-Maddin:
Исходное решение (устарело)
Используется
escape
иunescape
(которые теперь устарели, хотя все еще работает во всех современных браузерах):И последнее: я впервые столкнулся с этой проблемой при вызове API GitHub. Чтобы заставить это работать в (Mobile) Safari должным образом, мне фактически пришлось удалить все пробелы из источника base64, прежде чем я смогу даже декодировать источник. Актуально ли это в 2017 году, я не знаю:
источник
b64DecodeUnicode('4pyTIMOgIGxhIG1vZGU=');
теперь корректно выводится «✓ à la mode»decodeURIComponent(atob('4pyTIMOgIGxhIG1vZGU=').split('').map(x => '%' + x.charCodeAt(0).toString(16)).join(''))
не самый производительный код, но он есть.return String.fromCharCode(parseInt(p1, 16));
чтобы иметь совместимость с TypeScript.Вещи меняются. В побег / экранирования в методы устарели.
Вы можете кодировать строку URI перед ее кодированием в Base64. Обратите внимание, что это не создает кодировку UTF8 в кодировке Base64, а скорее создает данные в кодировке URL-адреса в кодировке Base64. Обе стороны должны согласовать одинаковую кодировку.
См. Рабочий пример здесь: http://codepen.io/anon/pen/PZgbPW
Для проблемы OP сторонняя библиотека, такая как js-base64, должна решить проблему.
источник
Если вам больше нравится рассматривать строки как байты, вы можете использовать следующие функции
источник
Вот обновленное решение 2018 года, описанное в ресурсах разработки Mozilla.
КОДИРОВАТЬ ИЗ UNICODE В B64
ДЛЯ ДЕКОДИРОВАНИЯ из B64 в UNICODE
источник
Полная статья, которая мне подходит : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Base64_encoding_and_decoding
Часть, в которой мы кодируем из Unicode / UTF-8, это
В настоящее время это один из наиболее часто используемых методов.
источник
Я предполагаю, что кому-то может понадобиться решение, которое создает широко используемый URI base64. Посетите,
data:text/plain;charset=utf-8;base64,4pi44pi54pi64pi74pi84pi+4pi/
чтобы увидеть демонстрацию (скопируйте URI данных, откройте новую вкладку, вставьте URI данных в адресную строку, затем нажмите Enter, чтобы перейти на страницу). Несмотря на то, что этот URI закодирован в формате base64, браузер по-прежнему может распознавать высокие кодовые точки и правильно их декодировать. Минимизированный кодер + декодер составляет 1058 байт (+ Gzip → 589 байт)Ниже приведен исходный код, использованный для его создания.
Затем, чтобы декодировать данные base64, либо HTTP получит данные как URI данных, либо воспользуйтесь функцией ниже.
Преимущество большей стандартизации заключается в том, что этот кодировщик и этот декодер более широко применимы, поскольку их можно использовать как действительный URL-адрес, который отображается правильно. Наблюдайте.
Приведенные выше фрагменты кода не только очень стандартизированы, но и работают очень быстро. Вместо косвенной цепочки преемственности, когда данные должны быть несколько раз преобразованы между различными формами (например, в ответе Риккардо Галли), приведенный выше фрагмент кода является настолько прямым, насколько это возможно. Он использует только один простой быстрый
String.prototype.replace
вызов для обработки данных при кодировании и только один для декодирования данных при декодировании. Еще один плюс заключается в том, что (особенно для больших строк)String.prototype.replace
позволяет браузеру автоматически обрабатывать базовое управление памятью при изменении размера строки, что приводит к значительному повышению производительности, особенно в вечнозеленых браузерах, таких как Chrome и Firefox, которые сильно оптимизируютString.prototype.replace
. Наконец, вишенка на торте заключается в том, что для пользователей, использующих латинские скрипты, кроме пользователей латинских скриптов, строки, которые не содержат кодовых точек выше 0x7f, обрабатываются очень быстро, потому что строка остается неизменной алгоритмом замены.Я создал репозиторий github для этого решения по адресу https://github.com/anonyco/BestBase64EncoderDecoder/
источник
Небольшая коррекция, unescape и escape устарели, поэтому:
источник
encodeURIComponent
это обратноеdecodeURIComponent
, то есть просто отменит преобразование. См. Stackoverflow.com/a/31412163/1534459 для подробного объяснения того, что происходит сescape
иunescape
.encodeURIComponent
он используется, заключается в том, чтобы правильно обрабатывать (весь диапазон) строки Unicode. Так напримерwindow.btoa(decodeURIComponent(encodeURIComponent('€')))
дает,Error: String contains an invalid character
потому что он такой же, какwindow.btoa('€')
иbtoa
не может кодировать€
.Вот пример кода будущего для браузеров, которого может не хватать
escape/unescape()
. Обратите внимание, что IE 9 и старше не поддерживаетatob/btoa()
, поэтому вам нужно будет использовать для них пользовательские функции base64.Более подробный пример кодирования и декодирования UTF-8 можно найти здесь: http://jsfiddle.net/47zwb41o/
источник
включая указанное выше решение, если проблема все еще возникает, попробуйте, как показано ниже. Рассмотрим случай, когда escape не поддерживается для TS.
для csv_content вы можете попробовать, как показано ниже.
источник