Мне нужно преобразовать строку кодирования base64 в ArrayBuffer. Строки base64 вводятся пользователем, они будут скопированы и вставлены из электронного письма, поэтому их нет при загрузке страницы. Я хотел бы сделать это в javascript, если это возможно, без вызова сервера ajax.
Эти ссылки показались мне интересными, но они мне не помогли:
ArrayBuffer в строку в кодировке base64
речь идет об обратном преобразовании из ArrayBuffer в base64, а не наоборот
http://jsperf.com/json-vs-base64/2
это выглядит хорошо, но я не могу понять, как использовать код.
Есть ли простой (возможно, собственный) способ выполнить преобразование? Благодарность
bytes[i] = binary_string.charCodeAt(i);
может ошибатьсяИспользование TypedArray.from :
Uint8Array.from(atob(base64_string), c => c.charCodeAt(0))
Производительность сравнивается с версией ответа Goran.it для цикла for.
источник
Uint8Array.from
прежнему мало совместим с некоторыми браузерами.ExecJS::RuntimeError: SyntaxError: Unexpected token: operator (>)
; (рельсы 5).buffer
свойство того, что возвращаетсяUint8Array
atob
илиbtoa
, вам просто нужно дать им правильный ввод.atob
нужна допустимая строка base64, иначе будет выдана ошибка. Иbtoa
требуется допустимая байтовая строка (также называемая двоичной строкой), которая представляет собой строку, содержащую символы в диапазоне 0-255. Если в вашей строке есть символы за пределами этого диапазона,btoa
будет выдана ошибка.Ответ Goran.it не работает из-за проблемы с юникодом в javascript - https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding .
В итоге я использовал функцию, указанную в блоге Даниэля Герреро: http://blog.danguer.com/2011/10/24/base64-binary-decoding-in-javascript/
Функция указана в ссылке на github: https://github.com/danguer/blog-examples/blob/master/js/base64-binary.js
Используйте эти строки
var uintArray = Base64Binary.decode(base64_string); var byteArray = Base64Binary.decodeArrayBuffer(base64_string);
источник
atob
вообще.decodeArrayBuffer
возвращаетArrayBuffer
размер, который всегда делится на 3, что я не понимаю, является ли это дизайном или ошибкой. Спрошу в проекте github.Только что нашел base64-arraybuffer, небольшой пакет npm с невероятно высоким уровнем использования, 5 миллионов загрузок в прошлом месяце (2017-08).
https://www.npmjs.com/package/base64-arraybuffer
Это может быть оно для всех, кто ищет лучшее стандартное решение.
источник
Асинхронное решение, лучше, когда данные большие:
// base64 to buffer function base64ToBufferAsync(base64) { var dataUrl = "data:application/octet-binary;base64," + base64; fetch(dataUrl) .then(res => res.arrayBuffer()) .then(buffer => { console.log("base64 to buffer: " + new Uint8Array(buffer)); }) } // buffer to base64 function bufferToBase64Async( buffer ) { var blob = new Blob([buffer], {type:'application/octet-binary'}); console.log("buffer to blob:" + blob) var fileReader = new FileReader(); fileReader.onload = function() { var dataUrl = fileReader.result; console.log("blob to dataUrl: " + dataUrl); var base64 = dataUrl.substr(dataUrl.indexOf(',')+1) console.log("dataUrl to base64: " + base64); }; fileReader.readAsDataURL(blob); }
источник
Для пользователей Node.js:
const myBuffer = Buffer.from(someBase64String, 'base64');
myBuffer будет иметь тип Buffer, который является подклассом Uint8Array. К сожалению, Uint8Array НЕ является ArrayBuffer, как просил OP. Но при манипулировании ArrayBuffer я почти всегда оборачиваю его Uint8Array или чем-то подобным, поэтому он должен быть близок к тому, что запрашивается.
источник
Javascript - прекрасная среда для разработки, поэтому кажется странным, что не дает решения этой небольшой проблемы. Решения, предлагаемые в другом месте на этой странице, потенциально медленные. Вот мое решение. Он использует встроенную функциональность, которая декодирует URL-адреса изображения и звука в формате base64.
var req = new XMLHttpRequest; req.open('GET', "data:application/octet;base64," + base64Data); req.responseType = 'arraybuffer'; req.onload = function fileLoaded(e) { var byteArray = new Uint8Array(e.target.response); // var shortArray = new Int16Array(e.target.response); // var unsignedShortArray = new Int16Array(e.target.response); // etc. } req.send();
Запрос на отправку не выполняется, если строка base 64 неправильно сформирована.
Тип mime (приложение / октет), вероятно, не нужен.
Проверено в хроме. Должен работать в других браузерах.
источник
Access Denied
об ошибке, которое, похоже, является ограничением CORS.Чистый JS - без строкового промежуточного этапа (без атоба)
Я пишу следующую функцию, которая напрямую преобразует base64 (без преобразования в строку на промежуточном этапе). ИДЕЯ
=
символами, удалите одно / два числа из выходного массиваНижеприведенное решение позволяет обрабатывать большие входные строки base64. Аналогичная функция для преобразования байтов в base64 без btoa ЗДЕСЬ
Показать фрагмент кода
function base64ToBytesArr(str) { const abc = [..."ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"]; // base64 alphabet let result = []; for(let i=0; i<str.length/4; i++) { let chunk = [...str.slice(4*i,4*i+4)] let bin = chunk.map(x=> abc.indexOf(x).toString(2).padStart(6,0)).join(''); let bytes = bin.match(/.{1,8}/g).map(x=> +('0b'+x)); result.push(...bytes.slice(0,3 - (str[4*i+2]=="=") - (str[4*i+3]=="="))); } return result; } // -------- // TEST // -------- let test = "Alice's Adventure in Wonderland."; console.log('test string:', test.length, test); let b64_btoa = btoa(test); console.log('encoded string:', b64_btoa); let decodedBytes = base64ToBytesArr(b64_btoa); // decode base64 to array of bytes console.log('decoded bytes:', JSON.stringify(decodedBytes)); let decodedTest = decodedBytes.map(b => String.fromCharCode(b) ).join``; console.log('Uint8Array', JSON.stringify(new Uint8Array(decodedBytes))); console.log('decoded string:', decodedTest.length, decodedTest);
источник
const str = "dGhpcyBpcyBiYXNlNjQgc3RyaW5n" const encoded = new TextEncoder().encode(str) // is Uint8Array const buf = encoded.buffer // is ArrayBuffer
источник