如何在javascript中将dataURL转换为文件对象?
如何在JavaScript中将dataURL转换为文件对象?
有时候,我们可能需要将dataURL(包含图像或其他文件的Base64编码字符串)转换为文件对象。下面是解决这个问题的方法:
首先,我们需要从dataURL创建一个blob对象。可以使用fetch函数来获取dataURL对应资源的响应,然后使用blob()方法将响应转换为blob对象。代码如下:
const response = await fetch(dataURL); const blob = await response.blob();
接下来,我们可以使用blob对象创建一个文件对象。文件对象需要传入blob对象、文件名和文件的相关属性(如文件类型和最后修改时间)。代码如下:
const file = new File( [blob], "fileName.jpg", { type: "image/jpeg", lastModified: new Date() } );
上述代码使用了await和fetch函数,但是我们可以使用then方法来替代await,以避免嵌套。代码如下:
await fetch(src).then(it => it.blob())
更好的做法是将代码拆分为两行,这样更加明确和易读。将await和then混合使用往往会导致困惑,而且与使用嵌套的await相比并没有明显的改进。我们不必将代码写在一行上。
另外,我们也可以将.then方法放在另一行,并且最好不要创建中间变量和常量声明。
通过上述方法,我们可以将dataURL转换为文件对象,以便在JavaScript中进行进一步处理和操作。
如何在JavaScript中将dataURL转换为文件对象?
问题的原因:
BlobBuilder已被弃用,不应再使用。应使用Blob代替BlobBuilder。代码非常简洁清晰。文件对象是继承自Blob对象的。可以同时使用它们与FormData对象。
解决方法:
使用以下函数将dataURL转换为Blob并发送到服务器:
function dataURLtoBlob(dataurl) { 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 Blob([u8arr], {type:mime}); }
示例:
var dataurl = 'data:text/plain;base64,aGVsbG8gd29ybGQ='; var blob = dataURLtoBlob(dataurl); var fd = new FormData(); fd.append("file", blob, "hello.txt"); var xhr = new XMLHttpRequest(); xhr.open('POST', '/server.php', true); xhr.onload = function(){ alert('upload complete'); }; xhr.send(fd);
另一种方法:
也可以使用fetch将URL转换为文件对象(文件对象具有name/fileName属性,这与blob对象不同)。
代码非常简短易用。
//将src加载并转换为File实例对象 //适用于任何类型的src,不仅限于图像src。 //返回一个解析为File实例的promise function srcToFile(src, fileName, mimeType){ return (fetch(src) .then(function(res){return res.arrayBuffer();}) .then(function(buf){return new File([buf], fileName, {type:mimeType});}) ); }
用法示例1:仅转换为文件对象
srcToFile( 'data:text/plain;base64,aGVsbG8gd29ybGQ=', 'hello.txt', 'text/plain' ) .then(function(file){ console.log(file); })
用法示例2:转换为文件对象并上传到服务器
srcToFile( 'data:text/plain;base64,aGVsbG8gd29ybGQ=', 'hello.txt', 'text/plain' ) .then(function(file){ console.log(file); var fd = new FormData(); fd.append("file", file); return fetch('/server.php', {method:'POST', body:fd}); }) .then(function(res){ return res.text(); }) .then(console.log) .catch(console.error) ;
我非常喜欢您的答案,因为它简洁明了,但是我真的不知道其他答案中ArrayBuffer的用法。您能解释一下ArrayBuffer的用法以及为什么在这里没有使用吗?
如果您没有查看Mozilla开发者网络的参考资料,请注意,fetch是一个实验性的功能,并不建议在生产代码中使用。太糟糕了,看起来很酷。
如果没有使用promise版本会怎样呢?
在这段内容中,原文提到如果需要通过ajax发送数据,则不需要使用`File`对象,只需要使用`Blob`和`FormData`对象即可。并且建议直接将base64字符串通过ajax发送给服务器,然后在服务器端使用PHP的`base64_decode`函数将其转换为二进制数据。接下来,文章中给出了一个在Chrome 13和WebKit nightlies中适用的代码示例,用于将dataURL转换为Blob对象的方法。然后,将Blob附加到一个新的FormData对象中,并使用ajax将其发送到服务器。在Firefox中,如果没有表单,则应创建一个空的FormData对象。最后,还提到了一些关于代码的改进和注意事项的评论。
根据以上内容,我们可以总结出这个问题的出现原因是需要将dataURL转换为文件对象,以便通过ajax发送给服务器。解决方法是通过使用JavaScript中的Blob对象和FormData对象来实现转换和发送。具体的实现方法可以参考提供的代码示例。
下面是整理后的文章:
如果需要将dataURL转换为文件对象并通过ajax发送给服务器,就不需要使用`File`对象,只需要使用`Blob`和`FormData`对象即可。并且可以直接将base64字符串通过ajax发送给服务器,然后在服务器端使用相应的函数将其转换为二进制数据。下面是一个可以在Chrome 13和WebKit nightlies中使用的标准代码示例,用于将dataURL转换为Blob对象:
function dataURItoBlob(dataURI) { var byteString = atob(dataURI.split(',')[1]); var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; var ab = new ArrayBuffer(byteString.length); var ia = new Uint8Array(ab); for (var i = 0; i < byteString.length; i++) { ia[i] = byteString.charCodeAt(i); } return new Blob([ab], {type: mimeString}); }
然后,只需将Blob对象附加到一个新的FormData对象中,并使用ajax将其发送到服务器:
var blob = dataURItoBlob(someDataUrl); var fd = new FormData(document.forms[0]); var xhr = new XMLHttpRequest(); fd.append("myFile", blob); xhr.open('POST', '/', true); xhr.send(fd);
需要注意的是,在Firefox中,如果没有表单,则应创建一个空的FormData对象。另外,还有一些关于代码改进和注意事项的评论,可以参考相关链接中的内容。
这就是将dataURL转换为文件对象并通过ajax发送给服务器的方法。如果你遇到了类似的问题,希望这篇文章对你有所帮助。