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거부 된 약속을 반환하는 함수 인 경우 호출에 의해 오류가 반환되지 않습니다. 던져 질 것이고 그것을 잡을 필요가있을 것입니다.
Dancrumb

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]A는 File의 sublcass입니다 유형은 Blob. 따라서와 함께 사용할 수 있습니다 FileReader.
전체 작업 예를 참조하십시오 .


2
을 FileReader API에 대한 자세한 읽어 developer.mozilla.org/en-US/docs/Web/API/FileReader 및 브라우저 지원 : caniuse.com/#feat=filereader
루카스 Liesis

7
base64를 변수로 캡처 한 다음 Google Apps Script로 보내려고하기 때문에을 사용하지 않고 함수 return reader.result에서 사용하려고했습니다 . 내가 가진 함수를 호출 : 다음에 콘솔에 인쇄하려고 그냥있어 . base64를 변수에 올바르게 할당하려면 어떻게해야합니까? getBase64()console.log(reader.result)var my_file_as_base64 = getBase64(file)console.log(my_file_as_base64 )undefined
user1063287

1
누군가 대답 할 수 있다면 위의 의견에서 질문을했습니다. stackoverflow.com/questions/47195119/…
user1063287 5

이 Base64 파일을 동일한 파일 이름으로 브라우저에서 열어야합니다. window.open (url, '_blank') 사용하여 파일을 열면 제대로 작동합니다. 파일 이름을 어떻게 지정할 수 있습니까? 도와주세요.
샤르마


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') 사용하여 파일을 열면 제대로 작동합니다. 파일 이름을 어떻게 지정할 수 있습니까? 도와주세요.
샤르마

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의 첫 번째 교체는 빈 파일을 캡처하는 것이고, 두 번째 교체는 쉼표가 없습니다-encode = reader.result.replace ( "data :", "") .replace (/^.*; base64, /, "");
user3333134

내 말은, 나는 그 혼수 상태를 정말로 놓쳤다. 놀라운 점은 백엔드를 전혀 신경 쓰지 않는 것처럼 보였지만 여전히 Excel 파일을 성공적으로 업로드 할 수있었습니다. 빈 파일 사용 사례를 고려하여 정규식을 수정했습니다. 감사.
Arnaud P

2
더 쉬운 버전이 resolve(reader.result.replace(/^.*,/, ''));있습니다. 코마 ,는 base64 알파벳 외부에 있으므로 코마를 포함하여 코마를 포함하여 발생하는 모든 것을 제거 할 수 있습니다. stackoverflow.com/a/13195218/1935128
Johnride

여기에 쓴 정규식에 따르면 (확실히 다시 실험해야 할 필요가 있음) data:쉼표 가 없을 수 있으므로 첫 번째 부분을 그대로 유지합니다. 이에 따라 답변을 업데이트했습니다.
Arnaud P

1
@ArnaudP Typescript error : 'string'속성에 'replace'속성이 없습니다. ArrayBuffer '.
Romel Gomez

12

JavaScript btoa () 함수를 사용하여 데이터를 base64로 인코딩 된 문자열로 변환 할 수 있습니다


6
btoa는 문자열에서만 작동합니다. 파일과 함께 사용하는 방법?
Vassily

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.