JavaScriptでファイルをbase64に変換する方法は?


186

今、私はこの行でFileオブジェクトを取得しています:

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

このファイルをbase 64のjson経由で送信する必要があります。base64文字列に変換するにはどうすればよいですか?

回答:


118

最新のES6方法(非同期/待機)

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:

エラーをキャッチしたい場合

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

このコードは正しくありません。await拒否されたPromiseを返す関数の場合、呼び出しによってエラーが返されることはありません。それがスローされ、それをキャッチする必要があります。
ダンクラム

1
非同期関数とプロミスの使用例
Thiago Frias

292

FileReader クラスを使用して解決策を試してください:

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

.files[0]Fileタイプであり、のサブクラスであることに注意してくださいBlob。したがって、で使用できますFileReader
完全な動作例を参照してください。


2
FileReader APIの詳細を読む:developer.mozilla.org/en-US/docs/Web/API/FileReaderおよびブラウザーサポート:caniuse.com/#feat=filereader
Lukas Liesis

7
base64を変数としてキャプチャし、それをGoogle Apps Scriptに送信したいので、(を使用するのreturn reader.resultではgetBase64()なくconsole.log(reader.result))関数から使用しようとしました。私はこの関数を次のように呼び出しました:var my_file_as_base64 = getBase64(file)でコンソールに出力しconsole.log(my_file_as_base64 )てみましundefinedた どうすればbase64を変数に適切に割り当てることができますか?
user1063287

1
上記のコメントから誰かが答えられるかどうか質問しました。 stackoverflow.com/questions/47195119/…–
user1063287

同じBase64ファイルを同じファイル名でブラウザーで開く必要があります。正常に機能しているwindow.open(url、 '_blank')を使用してファイルを開いていますが、それにファイル名を付けるにはどうすればよいですか?助けてください。
Munish Sharma


123

あなたがプロミスベースのソリューションを求めているなら、これはそれに適合した@Dmitriのコードです:

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

同じBase64ファイルを同じファイル名でブラウザーで開く必要があります。正常に機能しているwindow.open(url、 '_blank')を使用してファイルを開いていますが、それにファイル名を付けるにはどうすればよいですか?助けてください。
Munish Sharma

42

Dmitri Pavlutinとjoshua.palingの回答に基づいて、base64コンテンツを抽出し(最初のメタデータを削除)、パディングが正しく行われるようにする拡張バージョンを示します。

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、最初の置換は空のファイルをキャッチすることであり、2番目の置換はコンマがありません-エンコード= reader.result.replace( "data:"、 "").replace(/^.*; base64、/、 "");
user3333134 2018

私の言葉、私は確かにその昏睡を逃しました。信じられないことは、それが私のバックエンドをまったく邪魔しないようだったということです。それでも、Excelファイルを正常にアップロードすることができましたo_O。空のファイルの使用例も考慮に入れるように正規表現を修正しました。ありがとう。
Arnaud P

2
さらに簡単なバージョンがありますresolve(reader.result.replace(/^.*,/, ''));。コマ,はbase64アルファベットの外にあるので、コマまでのすべてのものを取り除くことができます。stackoverflow.com/a/13195218/1935128
Johnride

私は(私は確かに再び実験する必要があると思います)ここに書いた正規表現によると、ちょうどがあるかもしれませんが、ヘッドアップのために[OK]を感謝、data:であるように私は、その最初の部分をしておこう、任意のカンマなしで、ので。それに応じて答えを更新しました。
Arnaud P

1
@ArnaudP Typescriptエラー:プロパティ 'replace'がタイプ 'stringに存在しません| ArrayBuffer '。
Romel Gomez

12

JavaScript btoa()関数を使用して、データをbase64エンコードされた文字列に変換できます


6
btoaは文字列でのみ機能します。ファイルでどのように使用しますか?
Vassily 2016年

10
あなたは...何かのように最初のファイルを読み、この関数に渡す必要がありますjsfiddle.net/eliseosoto/JHQnk
Pranav Maniar

1
@PranavManiarフィドルが機能しなくなりました。リンクを更新できますか?
Dan

5

簡単に渡すことができるjson形式のファイルを取得するために私が書いたいくつかの関数を次に示します。

    //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
array.mapに基づいてすべてを約束することは素晴らしいです!少なくとも私にとっては。
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]);
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.