如何将 Base64 字符串转换为 javascript 文件对象,就像从文件输入表单一样

How to convert Base64 String to javascript file object like as from file input form?

本文关键字:文件 输入 表单 一样 Base64 字符串 转换 对象 javascript      更新时间:2023-09-26

我想将从文件中提取的 Base64String(例如:"AAAAA....~")转换为 javascript 文件对象。

我的意思是javascript文件对象是这样的代码:

.HTML:

<input type="file" id="selectFile" > 

.JS:

$('#selectFile').on('change', function(e) {
  var file = e.target.files[0];
  console.log(file)
}

'file' 变量是一个 JavaScript 文件对象。所以我想像这样将 base64 字符串转换为 javascript 文件对象。

我只想通过解码 base64 字符串(由文件中的其他应用程序编码)来获取文件对象,而无需 html 文件输入表单。

谢谢。

方式 1:仅适用于 dataURL,不适用于其他类型的 url。

function dataURLtoFile(dataurl, filename) {
    var arr = dataurl.split(','),
        mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[arr.length - 1]), 
        n = bstr.length, 
        u8arr = new Uint8Array(n);
    while(n--){
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new File([u8arr], filename, {type:mime});
}
//Usage example:
var file = dataURLtoFile('data:text/plain;base64,aGVsbG8=','hello.txt');
console.log(file);

方式2:适用于任何类型的URL,(http url,dataURL,blobURL等...

// return a promise that resolves with a File instance
function urltoFile(url, filename, mimeType){
    if (url.startsWith('data:')) {
        var arr = url.split(','),
            mime = arr[0].match(/:(.*?);/)[1],
            bstr = atob(arr[arr.length - 1]), 
            n = bstr.length, 
            u8arr = new Uint8Array(n);
        while(n--){
            u8arr[n] = bstr.charCodeAt(n);
        }
        var file = new File([u8arr], filename, {type:mime || mimeType});
        return Promise.resolve(file);
    }
    return fetch(url)
        .then(res => res.arrayBuffer())
        .then(buf => new File([buf], filename,{type:mimeType}));
}
//Usage example:
urltoFile('data:text/plain;base64,aGVsbG8=', 'hello.txt','text/plain')
.then(function(file){ console.log(file);});

const url = 'data:image/png;base6....';
fetch(url)
  .then(res => res.blob())
  .then(blob => {
    const file = new File([blob], "File name",{ type: "image/png" })
  })

base64 字符串 -> blob -> 文件。

这是

最新的async/await模式解决方案。

export async function dataUrlToFile(dataUrl: string, fileName: string): Promise<File> {
    const res: Response = await fetch(dataUrl);
    const blob: Blob = await res.blob();
    return new File([blob], fileName, { type: 'image/png' });
}

这是@cuixiping上面接受的答案的 Typescript 版本,现在使用 Buffer 而不是 atob()

我看到了使用 TypeScript 中的 atob() 的弃用警告,尽管它还没有完全弃用。只有一个重载。但是,我将我的转换为使用 Buffer 的弃用警告建议。它看起来更干净,因为它不需要额外的循环来转换每个字符。

  /***
   * Converts a dataUrl base64 image string into a File byte array
   * dataUrl example:
   * data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIsAAACLCAYAAABRGWr/AAAAAXNSR0IA...etc
   */
  dataUrlToFile(dataUrl: string, filename: string): File | undefined {
    const arr = dataUrl.split(',');
    if (arr.length < 2) { return undefined; }
    const mimeArr = arr[0].match(/:(.*?);/);
    if (!mimeArr || mimeArr.length < 2) { return undefined; }
    const mime = mimeArr[1];
    const buff = Buffer.from(arr[1], 'base64');
    return new File([buff], filename, {type:mime});
  }

在文件的顶部,您需要导入以使键入满意。

import { Buffer } from 'buffer';

不需要特殊的 npm 包。

const file = new File([
  new Blob(["decoded_base64_String"])
], "output_file_name");

您可以使用这样的库来解码 base64 并将其编码为 arrayBuffer。

我有一个非常相似的要求(从外部xml导入文件导入base64编码的图像。 在使用 xml2json-light 库转换为 json 对象后,我能够利用上面 cuixiping 的答案中的见解将传入的 b64 编码图像转换为文件对象。

const imgName = incomingImage['FileName'];
const imgExt = imgName.split('.').pop();
let mimeType = 'image/png';
if (imgExt.toLowerCase() !== 'png') {
    mimeType = 'image/jpeg';
}
const imgB64 = incomingImage['_@ttribute'];
const bstr = atob(imgB64);
let n = bstr.length;
const u8arr = new Uint8Array(n);
while (n--) {
  u8arr[n] = bstr.charCodeAt(n);
}
const file = new File([u8arr], imgName, {type: mimeType});

我的传入 json 对象在通过 xml2json-light 转换后有两个属性:文件名和_@ttribute(这是传入元素正文中包含的 b64 图像数据)。我需要根据传入的文件名扩展名生成 mime 类型。一旦我从 json 对象中提取/引用了所有部分,生成新的 File 对象是一项简单的任务(使用 cuixiping 提供的代码参考),该对象与我现有的类完全兼容,这些类期望从浏览器元素生成文件对象。

希望这有助于为其他人连接点。

起头来,

JAVASCRIPT

<script>
   function readMtlAtClient(){
       mtlFileContent = '';
       var mtlFile = document.getElementById('mtlFileInput').files[0];
       var readerMTL = new FileReader();
       // Closure to capture the file information.
       readerMTL.onload = (function(reader) {
           return function() {
               mtlFileContent = reader.result;
               mtlFileContent = mtlFileContent.replace('data:;base64,', '');
               mtlFileContent = window.atob(mtlFileContent);
           };
       })(readerMTL);
       readerMTL.readAsDataURL(mtlFile);
   }
</script>

.HTML

    <input class="FullWidth" type="file" name="mtlFileInput" value="" id="mtlFileInput" 
onchange="readMtlAtClient()" accept=".mtl"/>

然后 mtlFileContent 将您的文本作为解码字符串!

Typescript 的完整版本

async uploadImage(b64img: string) {
  var file = await this.urltoFile(b64img,'name.png',this.base64MimeType(b64img));
}
//return a promise that resolves with a File instance
urltoFile(url, filename, mimeType){
    return (fetch(url)
        .then(function(res){return res.arrayBuffer();})
        .then(function(buf){return new File([buf], filename,{type:mimeType});})
    );
}
//return mime Type of bs64
base64MimeType(encoded) {
    var result = null;
  
    if (typeof encoded !== 'string') {
      return result;
    }
  
    var mime = encoded.match(/data:([a-zA-Z0-9]+'/[a-zA-Z0-9-.+]+).*,.*/);
  
    if (mime && mime.length) {
      result = mime[1];
    }
  
    return result;
}

这对我有用 将base64图像转换为文件

这对我有用

信用
base64ToFile = (url: string) => {
let arr = url.split(',');
// console.log(arr)
let mime = arr[0].match(/:(.*?);/)![1];
let data = arr[1];
let dataStr = atob(data);
let n = dataStr.length;
let dataArr = new Uint8Array(n);
while (n--) {
  dataArr[n] = dataStr.charCodeAt(n);
}
let file = new File([dataArr], 'File.png', { type: mime });
return file;
};