如何将 Base64 字符串转换为 javascript 文件对象,如文件输入表单?
Posted
技术标签:
【中文标题】如何将 Base64 字符串转换为 javascript 文件对象,如文件输入表单?【英文标题】:How to convert Base64 String to javascript file object like as from file input form? 【发布时间】:2016-06-26 16:51:27 【问题描述】:我想将从文件中提取的 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[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););
【讨论】:
警告,在我看来 File 对象仅在 Firefox 上可用。首选 Blob 对象:developer.mozilla.org/en-US/docs/Web/API/Blob 我使用你的**第二种方式**上传pdf缩略图,但是上传完成后显示黑色图像 @ChetanBuddh 这可能是由您的代码的其他问题引起的。你能把你的代码粘贴到 JSFiddle 中吗? 在方式 1 中,我得到的是 [object Object] 而不是 [object file]。我怎样才能得到[目标文件].@cuixiping 我可以得到你的帮助吗@cuixiping【参考方案2】: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 你能详细说明一下吗? 如果您有一个具有 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/…【参考方案3】:这是最新的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' );
【讨论】:
评价这个,因为这对我来说是最好的方法。加上使用打字稿【参考方案4】:我有一个非常相似的要求(从外部 xml 导入文件导入 base64 编码图像。使用xml2json-light library 转换为 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 图像数据。)我需要根据传入的 mime-type文件扩展名。一旦我从 json 对象中提取/引用了所有部分,生成新的 File 对象是一项简单的任务(使用 cuixiping 提供的代码参考),它与我现有的类完全兼容,这些类期望从浏览器元素生成文件对象.
希望这有助于为其他人连接点。
【讨论】:
【参考方案5】:请注意,
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 将您的文本作为解码字符串!
【讨论】:
【参考方案6】:这是@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 包。
【讨论】:
【参考方案7】:const file = new File([
new Blob(["decoded_base64_String"])
], "output_file_name");
您可以使用像 this 这样的库来将 base64 解码和编码为 arrayBuffer。
【讨论】:
以上是关于如何将 Base64 字符串转换为 javascript 文件对象,如文件输入表单?的主要内容,如果未能解决你的问题,请参考以下文章
如何将图像转换为 Base64 字符串,并转换回图像,保存到 azure blob
如何使用javascript将字符串转换为base64? [复制]