如何在 JavaScript 中将文件转换为 base64

How to convert file to base64 in JavaScript?

本文关键字:文件 转换 base64 JavaScript      更新时间:2023-09-26

UPD TypeScript 版本也可在答案中使用

现在我通过这一行获取文件对象:

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

我需要通过 base 64 中的 json 发送此文件。我应该怎么做才能将其转换为 base64 字符串?

使用 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一起使用。
请参阅完整的工作示例。

Modern ES6 way (async/await(

const toBase64 = file => new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result);
    reader.onerror = reject;
});
async function Main() {
   const file = document.querySelector('#myfile').files[0];
   console.log(await toBase64(file));
}
Main();

上级:

如果要捕获错误

async function Main() {
   const file = document.querySelector('#myfile').files[0];
   try {
      const result = await toBase64(file);
      return result
   } catch(error) {
      console.error(error);
      return;
   }
   //...
}

如果您追求的基于承诺的解决方案,那么 @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)
);

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

TypeScript 版本

const file2Base64 = (file:File):Promise<string> => {
    return new Promise<string> ((resolve,reject)=> {
         const reader = new FileReader();
         reader.readAsDataURL(file);
         reader.onload = () => resolve(reader.result?.toString() || '');
         reader.onerror = error => reject(error);
     })
    }

JavaScript btoa(( 函数可用于将数据转换为 base64 编码字符串

<div>
    <div>
        <label for="filePicker">Choose or drag a file:</label><br>
        <input type="file" id="filePicker">
    </div>
    <br>
    <div>
        <h1>Base64 encoded version</h1>
        <textarea id="base64textarea" 
                  placeholder="Base64 will appear here" 
                  cols="50" rows="15"></textarea>
    </div>
</div>
var handleFileSelect = function(evt) {
    var files = evt.target.files;
    var file = files[0];
    if (files && file) {
        var reader = new FileReader();
        reader.onload = function(readerEvt) {
            var binaryString = readerEvt.target.result;
            document.getElementById("base64textarea").value = btoa(binaryString);
        };
        reader.readAsBinaryString(file);
    }
};
if (window.File && window.FileReader && window.FileList && window.Blob) {
    document.getElementById('filePicker')
            .addEventListener('change', handleFileSelect, false);
} else {
    alert('The File APIs are not fully supported in this browser.');
}

以下是我编写的几个函数,用于获取可以轻松传递的 json 格式的文件:

    //takes an array of JavaScript File objects
    function getFiles(files) {
        return Promise.all(files.map(getFile));
    }
    //take a single JavaScript File object
    function getFile(file) {
        const 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,
                    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);
    
const fileInput = document.querySelector('input');
fileInput.addEventListener('change', (e) => {
// get a reference to the file
const file = e.target.files[0];
// encode the file using the FileReader API
const reader = new FileReader();
reader.onloadend = () => {
    // use a regex to remove data url part
    const base64String = reader.result
        .replace('data:', '')
        .replace(/^.+,/, '');
    // log to console
    // logs wL2dvYWwgbW9yZ...
    console.log(base64String);
};
reader.readAsDataURL(file);});

我使用了这个简单的方法,并且它已成功运行

 function  uploadImage(e) {
  var file = e.target.files[0];
    let reader = new FileReader();
    reader.onload = (e) => {
    let image = e.target.result;
    console.log(image);
    };
  reader.readAsDataURL(file);
  
}
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]);
    }
}

使用以下方式将任何文件转换为 base64 -

_fileToBase64(file: File) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result.toString().substr(reader.result.toString().indexOf(',') + 1));
    reader.onerror = error => reject(error);
  });
}

此页面是搜索如何将file对象转换为字符串时的第一个匹配项。如果您不关心base64,那么问题的答案很简单:

    str = await file.text()

通过添加扩展上述解决方案,以及我需要的用例能够循环访问表单上的多个字段并获取其值并且由于一个是文件,它导致了异步要求的问题

这样解决:

    async collectFormData() {
        // Create the file parsing promise
        const toBase64 = file => new Promise((resolve, reject) => {
            const reader = new FileReader();
            reader.readAsDataURL(file);
            reader.onload = () => resolve(reader.result);
            reader.onerror = error => reject(error);
        });
    
        
        let form_vals = []
        let els = [] // Form elements collection
        // This is separate because wrapping the await in a callback
        // doesn't work 
        $(`.form-field`).each(function (e) {
            els.push(this) // add to the collection of form fields
        })
        // Loop through the fields to collect information 
        for (let elKey in els) {
            let el = els[elKey]
            // If the field is input of type file. call the base64 parser
            if ($(el).attr('type') == 'file') {
                // Get a reference to the file
                const file = el.files[0];
                form_vals.push({
                    "key": el.id,
                    "value": await toBase64(file)
                })
        }

        // TODO: The rest of your code here form_vals will now be 
        // populated in time for a server post
    }

这纯粹是为了解决处理多个领域的问题以更流畅的方式

const file_to_base64 = async (a_file: File) => {
  let a_function = 
    (file: File) => new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.readAsDataURL(file);
      reader.onload = () => {
        let base64_string = String(reader.result).split(",")[1]
        resolve(base64_string)
      };
      reader.onerror = error => reject(error);
    })
    return (await a_function(a_file) as string)
}

这有效

// fileObj: File
const base64 = window.URL.createObjectURL(fileObj);
// You can use it with <img src={base64} />