JavaScript dosya base64 dönüştürmek nasıl?


188

Şimdi bu nesne ile File nesnesi alıyorum:

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

Bu dosyayı base 64 içindeki json ile göndermem gerekiyor. Base64 dizesine dönüştürmek için ne yapmalıyım?

Yanıtlar:


120

Modern ES6 yolu (zaman uyumsuz / beklemede )

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:

Hataları yakalamak istiyorsanız

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;
   }
   //...
}

Bu kod yanlış. awaitReddedilen bir Sözü döndüren bir işlev varsa , çağrı tarafından döndürülen bir Hata almazsınız; atılacak ve onu yakalamanız gerekecek.
Dancrumb

1
Eşzamansız işlevlerin ve vaatlerin kullanımına harika bir örnek
Thiago Frias

293

FileReader Sınıfı kullanarak çözümü deneyin :

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

Bunun bir sublcass olan .files[0]bir Filetür olduğuna dikkat edin Blob. Böylece ile kullanılabilir FileReader.
Çalışma örneğinin tamamına bakın .


2
FileReader API hakkında daha fazla bilgi edinin: developer.mozilla.org/en-US/docs/Web/API/FileReader ve tarayıcı desteği: caniuse.com/#feat=filereader
Lukas Liesis

7
Ben kullanmaya çalıştı return reader.resultdan getBase64()(kullanmak yerine işlevin console.log(reader.result)i bir değişken olarak base64 yakalamak (ve ardından da Google Apps Kodu göndermek) istediğim için). Ben fonksiyonu çağırdı: var my_file_as_base64 = getBase64(file)ve sonra konsol ile yazdırmak için çalıştı console.log(my_file_as_base64 )ve sadece var undefined. Base64 değişkenini nasıl düzgün bir şekilde atayabilirim?
user1063287

1
Birisi cevaplayabilirse yukarıdaki yorumdan bir soru yaptım. stackoverflow.com/questions/47195119/…
user1063287

Bu Base64 dosyasını aynı dosya adına sahip tarayıcıda açmam gerekiyor, iyi çalışan window.open (url, '_blank') kullanarak açıyorum, dosya adını nasıl verebilirim? lütfen yardım et.
Munish Sharma


124

Söz tabanlı bir çözüm peşindeyseniz, bu @ Dmitri'nin kodu buna uyarlanmıştır:

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)
);

Bu Base64 dosyasını aynı dosya adına sahip tarayıcıda açmam gerekiyor, iyi çalışan window.open (url, '_blank') kullanarak açıyorum, dosya adını nasıl verebilirim? lütfen yardım et.
Munish Sharma

42

Dmitri Pavlutin ve joshua.paling cevaplarına dayanarak, burada base64 içeriğini ayıklayan (başlangıçtaki meta verileri kaldıran) ve ayrıca dolgunun doğru şekilde yapılmasını sağlayan genişletilmiş bir sürüm .

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, ilk değiştirme boş dosyayı yakalamak, ikinci değiştirme eksik virgül - encoded = reader.result.replace ("data:", "") .replace (/^.*; base64, /, "");
user3333134

Sözüm, o komayı gerçekten özledim. İnanılmaz olan şey, arka ucumu hiç rahatsız etmiyor gibi görünüyordu, hala excel dosyalarını başarıyla o_O yükleyebildim. Boş dosya kullanım durumunuzu da dikkate almak için normal ifadeyi düzelttim. Teşekkürler.
Arnaud P

2
Bir daha da kolay versiyonu var: resolve(reader.result.replace(/^.*,/, ''));. Koma ,base64 alfabesinin dışında olduğundan, komaya kadar ve komaya kadar gelen her şeyi çıkarabiliriz. stackoverflow.com/a/13195218/1935128
Johnride

Tamam yazdığın için teşekkürler, burada yazdığım regex'e göre (emin olmak için tekrar denemem gerekir), data:herhangi bir virgül olmadan olabilir , bu yüzden ilk kısmı olduğu gibi tutacağım. Cevabı buna göre güncelledim.
Arnaud P

1
@ArnaudP Typescript hatası: 'string' türünde 'replace' özelliği yok | ArrayBuffer'.
Romel Gomez

12

JavaScript btoa () işlevi, verileri base64 kodlu dizeye dönüştürmek için kullanılabilir


6
btoa sadece string ile çalışır. Dosya ile nasıl kullanılır?
Vassily

10
önce dosyayı okumak ve daha sonra bu işleve geçmek zorunda kalacak
Pranav Maniar

1
@PranavManiar Kemanınız artık çalışmıyor. Bağlantıyı güncelleyebilir misiniz?
Dan

5

Kolayca iletilebilen json formatında bir dosya almak için yazdığım birkaç fonksiyon:

    //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
Bir dizi.map tabanlı, tüm söz veriyorum harika çalışıyor! En azından benim için.
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]);
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.