Создание Blob или файла из двоичной строки JavaScript изменяет количество байтов?
Я играл с несколькими библиотеками шифрования JS (CryptoJS, SJCL) и обнаружил проблемы, связанные с API-интерфейсами Blob/File и двоичными строками JavaScript.
Я понял, что шифрование даже не очень актуально, так что здесь очень упрощенный сценарий. Просто прочитайте файл при использовании readAsBinaryString, а затем создайте Blob:
>>> reader.result
"GIF89a����ÿÿÿÿÿÿ!þCreated with GIMP�,�������D�;"
>>> reader.result.length
56
>>> typeof reader.result
"string"
>>> blob = new Blob([reader.result], {type: "image/gif"})
Blob { size=64, type="image/gif", constructor=function(), more...}
Я создал JSFiddle, который будет в основном делать следующее: он просто читает любой произвольный файл, создает из него blob и выводит длину vs size:
http://jsfiddle.net/6L82t/1/
Похоже, что при создании Blob из "двоичной (javascript) строки" что-то с кодировкой символов заканчивается результатом.
Если используется недвоичный файл, вы увидите, что длины Blob и исходной двоичной строки идентичны.
Итак, есть что-то, что происходит при попытке создать Blob/File из строки Javascript, не являющейся открытым текстом, и мне нужно, чтобы этого не произошло. Я думаю, что это может иметь какое-то отношение к тому, что строки JS - это UTF-16?
Здесь есть (возможно) связанная тема:
API-интерфейс HTML5 читается как текстовый и двоичный
Нужно ли, возможно, взять дешифрованные результаты (UTF-16) и "преобразовать" их в UTF-8 перед тем, как поместить их в Blob/File?
Работая с кем-то из # html5 на Freenode, мы определили, что если вы сразу читаете ArrayBuffer, а затем создаете blob из этого, сначала используя Uint8Array, байты работают просто отлично. Вы можете увидеть скрипку, которая по существу делает это здесь:
http://jsfiddle.net/GH7pS/4/
Проблема в том, что, по крайней мере, в моем сценарии, я получаю двоичную строку и хотел бы выяснить, как напрямую преобразовать ее в Blob, чтобы затем я мог использовать загрузку html5, чтобы позволить пользователю нажмите, чтобы загрузить blob напрямую.
Спасибо!
Ответы
Ответ 1
Похоже, что при создании Blob из "двоичной (javascript) строки" что-то с кодировкой символов заканчивается результатом.
Да. Этот пост, который вы читаете, объясняет, как создается "двоичная строка".
Конструктор Blob
отличается от
- Пусть
s
является результатом преобразования [строки] в последовательность Unicode символов с использованием алгоритма для этого в WebIDL. - Кодируйте
s
как UTF-8 и добавьте полученные байты в [blob].
Мы определили, что если вы читаете ArrayBuffer напрямую, а затем создаете blob из этого, сначала используя Uint8Array, байты работают просто отлично.
Да, это то, как он должен работать. Просто выполните шифрование в Typed Array, где вы обрабатываете байты отдельно, а не на некоторой строке.
Проблема в том, что, по крайней мере, в моем сценарии, я получаю двоичную строку
Опять: постарайтесь не делать этого. бинарные строки устарели.
Я хотел бы выяснить, как напрямую преобразовать двоичную строку в Blob. Должен ли я взять дешифрованные результаты (UTF-16) и "преобразовать" их в UTF-8 перед тем, как поместить их в Blob/File?
Нет, лучше не пытайтесь преобразовывать строки. Вместо этого создайте Uint8Array
(Uint8Array) для байтов, которые вы хотите получить из двоичной строки.
Это должно сделать это (непроверено):
var bytes = new Uint8Array(str.length);
for (var i=0; i<str.length; i++)
bytes[i] = str.charCodeAt(i);