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

IT技术 javascript html forms file base64
2021-02-09 07:20:08

我想将从文件中提取的 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 文件输入表单。

谢谢你。

5个回答

方式一:只对dataURL有效,对其他类型的url无效。

 function dataURLtoFile(dataurl, filename) {
 
        var arr = dataurl.split(','),
            mime = arr[0].match(/:(.*?);/)[1],
            bstr = atob(arr[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,aGVsbG8gd29ybGQ=','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){
        return (fetch(url)
            .then(function(res){return res.arrayBuffer();})
            .then(function(buf){return new File([buf], filename,{type:mimeType});})
        );
    }
    
    //Usage example:
    urltoFile('data:text/plain;base64,aGVsbG8gd29ybGQ=', 'hello.txt','text/plain')
    .then(function(file){ console.log(file);});

@ChetanBuddh 这可能是由您的代码的其他问题引起的。你能把你的代码粘贴到 JSFiddle 中吗?
2021-03-21 07:20:08
在方式 1 中,我得到的是 [object Object] 而不是 [object file]。我怎样才能得到[目标文件]。@cuixiping
2021-03-24 07:20:08
我可以得到你的帮助@cuixiping
2021-03-28 07:20:08
我使用您的**第二种方式 ** 上传 pdf 缩略图,但上传完成后显示黑色图像
2021-03-30 07:20:08
警告,在我看来 File 对象仅在 Firefox 上可用。首选 Blob 对象:developer.mozilla.org/en-US/docs/Web/API/Blob
2021-04-09 07:20:08
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 -> 文件。

@MaxGabriel 你能详细说明一下吗?
2021-03-14 07:20:08
注意:这与大多数内容安全策略不兼容,如果您有一个
2021-04-11 07:20:08
如果您有一个带有 connect-src 属性的 CSP 将您的 Javascript 可以加载的 URL 列入白名单,它将拒绝它并显示错误:“拒绝连接到 'data:text/plain;base64,aGVsbG8gd29ybGQ=' 因为它违反了以下内容内容安全策略指令:“connect-src <...>”。您可以拥有 CSP 白名单数据 URL,但 MDN 警告:“这是不安全的;攻击者还可以注入任意数据:URI。谨慎使用它,绝对不要用于脚本。” developer.mozilla.org/en-US/docs/Web/HTTP/Headers/...
2021-04-11 07:20:08

这是最新的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' });
}
评价这个,因为这对我来说是最好的方法。加上使用typescript
2021-04-06 07:20:08

我有一个非常相似的要求(从外部 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 转换后有两个属性:FileName 和 _@ttribute(这是包含在传入元素主体中的 b64 图像数据。)我需要根据传入的 FileName 扩展名生成 mime-type。一旦我从 json 对象中提取/引用了所有部分,这是一个简单的任务(使用 cuixiping 提供的代码引用)来生成新的 File 对象,该对象与我现有的类完全兼容,该类期望从浏览器元素生成文件对象.

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

当心,

Java脚本

<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 将您的文本作为解码字符串!