Bagaimana cara mengonversi file ke base64 di JavaScript?


186

Sekarang saya mendapatkan objek File dengan baris ini:

file = document.querySelector('#files > input[type="file"]').files[0]

Saya perlu mengirim file ini melalui json di basis 64. Apa yang harus saya lakukan untuk mengubahnya menjadi string base64?

Jawaban:


118

Cara ES6 modern (async / menunggu)

const toBase64 = file => new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result);
    reader.onerror = error => reject(error);
});

async function Main() {
   const file = document.querySelector('#myfile').files[0];
   console.log(await toBase64(file));
}

Main();

UPD:

Jika Anda ingin menangkap kesalahan

async function Main() {
   const file = document.querySelector('#myfile').files[0];
   const result = await toBase64(file).catch(e => Error(e));
   if(result instanceof Error) {
      console.log('Error: ', result.message);
      return;
   }
   //...
}

Kode ini salah. Jika Anda awaitsuatu fungsi yang mengembalikan Janji yang ditolak, Anda tidak akan mendapatkan Kesalahan yang dikembalikan oleh panggilan; itu akan dibuang dan Anda harus menangkapnya.
— Dancrumb

1
Contoh bagus penggunaan fungsi dan janji async
— Thiago Frias

292

Coba solusinya menggunakan FileReader kelas :

function getBase64(file) {
   var reader = new FileReader();
   reader.readAsDataURL(file);
   reader.onload = function () {
     console.log(reader.result);
   };
   reader.onerror = function (error) {
     console.log('Error: ', error);
   };
}

var file = document.querySelector('#files > input[type="file"]').files[0];
getBase64(file); // prints the base64 string

Perhatikan bahwa itu .files[0]adalah Filetipe, yang merupakan sub dari dari Blob. Dengan demikian dapat digunakan dengan FileReader.
Lihat contoh kerja lengkap .


2
baca lebih lanjut tentang FileReader API: developer.mozilla.org/en-US/docs/Web/API/FileReader dan dukungan browser: caniuse.com/#feat=filereader
— Lukas Liesis

7
Saya mencoba menggunakan return reader.resultdari getBase64()fungsi (daripada menggunakan console.log(reader.result)) karena saya ingin menangkap base64 sebagai variabel (dan kemudian mengirimkannya ke Google Apps Script). Saya memanggil fungsi dengan: var my_file_as_base64 = getBase64(file)dan kemudian mencoba mencetak ke konsol dengan console.log(my_file_as_base64 )dan baru saja undefined. Bagaimana cara menetapkan base64 dengan benar ke variabel?
— user1063287

1
Saya membuat pertanyaan dari komentar di atas jika ada yang bisa menjawab. stackoverflow.com/questions/47195119/…
— user1063287

Saya perlu membuka file Base64 ini di browser dengan nama file yang sama, saya membukanya menggunakan window.open (url, '_blank') yang berfungsi dengan baik, bagaimana saya bisa memberikan nama file untuk itu? tolong bantu.
— Munish Sharma

Terima kasih! Saya pikir ini tidak dijelaskan dengan baik di developer.mozilla.org/en-US/docs/Web/API/FileReader/…
— johey

123

Jika Anda mencari solusi berbasis janji, ini adalah kode @ Dmitri yang disesuaikan untuk itu:

function getBase64(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result);
    reader.onerror = error => reject(error);
  });
}

var file = document.querySelector('#files > input[type="file"]').files[0];
getBase64(file).then(
  data => console.log(data)
);

Saya perlu membuka file Base64 ini di browser dengan nama file yang sama, saya membukanya menggunakan window.open (url, '_blank') yang berfungsi dengan baik, bagaimana saya bisa memberikan nama file untuk itu? tolong bantu.
— Munish Sharma

42

Membangun pada Dmitri Pavlutin dan joshua.paling menjawab, inilah versi yang diperpanjang yang mengekstrak konten base64 (menghapus metadata di awal) dan juga memastikan bantalan dilakukan dengan benar .

function getBase64(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => {
      let encoded = reader.result.toString().replace(/^data:(.*,)?/, '');
      if ((encoded.length % 4) > 0) {
        encoded += '='.repeat(4 - (encoded.length % 4));
      }
      resolve(encoded);
    };
    reader.onerror = error => reject(error);
  });
}

2
Chrome 69, ganti pertama adalah untuk menangkap file kosong, ganti kedua hilang koma - dikodekan = reader.result.replace ("data:", "") .replace (/^.*; base64, /, "" ");
— user3333134

Kata saya, saya memang merindukan koma itu. Yang luar biasa adalah sepertinya tidak mengganggu backend saya sama sekali, saya masih dapat mengunggah file excel dengan sukses o_O. Saya telah memperbaiki regex untuk memasukkan case use file kosong Anda ke dalam akun juga. Terima kasih.
— Arnaud P

2
Aku punya versi lebih mudah: resolve(reader.result.replace(/^.*,/, ''));. Karena koma ,berada di luar alfabet base64, kita dapat menghapus apa pun yang muncul sampai dan termasuk koma. stackoverflow.com/a/13195218/1935128
— Johnride

Ok terima kasih untuk kepala, meskipun menurut regex yang saya tulis di sini (saya perlu bereksperimen lagi untuk memastikan), mungkin saja ada data:, tanpa koma, jadi saya akan menjaga bagian pertama seperti apa adanya. Saya telah memperbarui jawabannya.
— Arnaud P

1
@ArnaudP Kesalahan skrip: Properti 'ganti' tidak ada pada tipe 'string | ArrayBuffer '.
— Romel Gomez

12

Fungsi JavaScript btoa () dapat digunakan untuk mengubah data menjadi string yang disandikan base64


6
Btoa hanya bekerja dengan string. Bagaimana cara menggunakannya dengan file?
— Vassily

10
Anda harus membaca file terlebih dahulu dan kemudian meneruskannya ke fungsi ini .. Sesuatu seperti jsfiddle.net/eliseosoto/JHQnk
— Pranav Maniar

1
@PranavManiar Biola Anda tidak lagi berfungsi. Bisakah Anda memperbarui tautannya?
— Dan

5

Berikut adalah beberapa fungsi yang saya tulis untuk mendapatkan file dalam format json yang dapat diedarkan dengan mudah:

    //takes an array of JavaScript File objects
    function getFiles(files) {
        return Promise.all(files.map(file => getFile(file)));
    }

    //take a single JavaScript File object
    function getFile(file) {
        var reader = new FileReader();
        return new Promise((resolve, reject) => {
            reader.onerror = () => { reader.abort(); reject(new Error("Error parsing file"));}
            reader.onload = function () {

                //This will result in an array that will be recognized by C#.NET WebApi as a byte[]
                let bytes = Array.from(new Uint8Array(this.result));

                //if you want the base64encoded file you would use the below line:
                let base64StringFile = btoa(bytes.map((item) => String.fromCharCode(item)).join(""));

                //Resolve the promise with your custom file structure
                resolve({ 
                    bytes: bytes,
                    base64StringFile: base64StringFile,
                    fileName: file.name, 
                    fileType: file.type
                });
            }
            reader.readAsArrayBuffer(file);
        });
    }

    //using the functions with your file:

    file = document.querySelector('#files > input[type="file"]').files[0]
    getFile(file).then((customJsonFile) => {
         //customJsonFile is your newly constructed file.
         console.log(customJsonFile);
    });

    //if you are in an environment where async/await is supported

    files = document.querySelector('#files > input[type="file"]').files
    let customJsonFiles = await getFiles(files);
    //customJsonFiles is an array of your custom files
    console.log(customJsonFiles);

1
Berjanjilah semua, berbasis di array.map berfungsi dengan baik! Setidaknya untuk saya.
— davidwillianx

0
onInputChange(evt) {
    var tgt = evt.target || window.event.srcElement,
    files = tgt.files;
    if (FileReader && files && files.length) {
        var fr = new FileReader();
        fr.onload = function () {
            var base64 = fr.result;
            debugger;
        }
        fr.readAsDataURL(files[0]);
    }
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.