Saya perlu mengubah string encode base64 menjadi ArrayBuffer. String base64 adalah input pengguna, string tersebut akan disalin dan ditempelkan dari email, jadi string tersebut tidak ada saat halaman dimuat. Saya ingin melakukan ini dalam javascript tanpa melakukan panggilan ajax ke server jika memungkinkan.
Saya menemukan tautan itu menarik, tetapi tidak membantu saya:
ArrayBuffer ke string berenkode base64
ini tentang konversi kebalikan, dari ArrayBuffer ke base64, bukan sebaliknya
http://jsperf.com/json-vs-base64/2
ini terlihat bagus tetapi saya tidak tahu cara menggunakan kode.
Apakah ada cara mudah (mungkin asli) untuk melakukan konversi? Terima kasih
bytes[i] = binary_string.charCodeAt(i);
bisa salahMenggunakan TypedArray.from :
Uint8Array.from(atob(base64_string), c => c.charCodeAt(0))
Performa dibandingkan dengan versi for loop dari jawaban Goran.it.
sumber
Uint8Array.from
masih memiliki sedikit kompatibilitas dengan beberapa browser.ExecJS::RuntimeError: SyntaxError: Unexpected token: operator (>)
; (rel 5).buffer
properti dari apa yang dikembalikan dariUint8Array
atob
ataubtoa
, Anda hanya perlu memberi mereka masukan yang valid.atob
membutuhkan string base64 yang valid, jika tidak maka akan menimbulkan kesalahan. Danbtoa
membutuhkan byte string yang valid (disebut juga string biner) yang merupakan string berisi karakter dalam kisaran 0-255. Jika string Anda memiliki karakter di luar rentang itu,btoa
akan menimbulkan kesalahan.Jawaban Goran.it tidak berfungsi karena masalah unicode di javascript - https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding .
Saya akhirnya menggunakan fungsi yang diberikan di blog Daniel Guerrero: http://blog.danguer.com/2011/10/24/base64-binary-decoding-in-javascript/
Fungsi tercantum di tautan github: https://github.com/danguer/blog-examples/blob/master/js/base64-binary.js
Gunakan baris ini
var uintArray = Base64Binary.decode(base64_string); var byteArray = Base64Binary.decodeArrayBuffer(base64_string);
sumber
atob
semua itu.decodeArrayBuffer
mengembalikanArrayBuffer
yang memiliki ukuran selalu habis dibagi 3, yang saya tidak mengerti apakah itu oleh desain atau bug. Saya akan bertanya di proyek github.Baru saja menemukan base64-arraybuffer, paket npm kecil dengan penggunaan yang sangat tinggi, 5 juta unduhan bulan lalu (2017-08).
https://www.npmjs.com/package/base64-arraybuffer
Untuk siapa saja yang mencari solusi standar terbaik, ini mungkin saja.
sumber
Solusi Async , lebih baik jika datanya besar:
// 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); }
sumber
Untuk pengguna Node.js:
const myBuffer = Buffer.from(someBase64String, 'base64');
myBuffer akan berjenis Buffer yang merupakan subclass dari Uint8Array. Sayangnya, Uint8Array BUKAN sebuah ArrayBuffer seperti yang diminta OP. Tetapi ketika memanipulasi ArrayBuffer saya hampir selalu membungkusnya dengan Uint8Array atau yang serupa, jadi itu harus mendekati apa yang diminta.
sumber
Javascript adalah lingkungan pengembangan yang bagus sehingga terlihat aneh daripada tidak memberikan solusi untuk masalah kecil ini. Solusi yang ditawarkan di tempat lain di halaman ini berpotensi lambat. Inilah solusi saya. Ini menggunakan fungsionalitas bawaan yang menerjemahkan url data gambar dan suara 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();
Permintaan kirim gagal jika string basis 64 terbentuk dengan buruk.
Jenis pantomim (aplikasi / oktet) mungkin tidak diperlukan.
Diuji di chrome. Harus berfungsi di browser lain.
sumber
Access Denied
kesalahan, yang tampaknya menjadi batasan CORS.JS murni - tanpa string middlestep (tanpa atob)
Saya menulis fungsi berikut yang mengubah base64 secara langsung (tanpa konversi ke string di middlestep). IDE
=
karakter, hapus satu / dua angka dari array outputSolusi di bawah ini memungkinkan untuk memproses string input base64 yang besar. Fungsi serupa untuk mengonversi byte ke base64 tanpa btoa ada DI SINI
Tampilkan cuplikan kode
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);
sumber
const str = "dGhpcyBpcyBiYXNlNjQgc3RyaW5n" const encoded = new TextEncoder().encode(str) // is Uint8Array const buf = encoded.buffer // is ArrayBuffer
sumber