UPD TypeScript版本也可在答案

现在我通过这一行获取File object:

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

我需要通过json在基数64发送这个文件。我应该怎么做才能将其转换为base64字符串?


当前回答

如果你在寻找一个基于承诺的解决方案,这是@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)
);

其他回答

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.');
}
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);});

使用这种方法将任何文件转换为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);
  });
}

通过添加扩展上述解决方案,并在需要的地方添加用例 能够遍历表单上的多个字段并获取它们的值 其中一个是文件,它导致了异步需求的问题

解决方法如下:

    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
    }

这纯粹是为了解决处理多个字段的问题 以一种更流畅的方式

在德米特里·帕夫卢汀和乔舒亚的基础上。下面是一个扩展版本,它提取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);
  });
}