如何在 JavaScript 中将 Blob 转换为文件

Posted

技术标签:

【中文标题】如何在 JavaScript 中将 Blob 转换为文件【英文标题】:How to convert Blob to File in JavaScript 【发布时间】:2015-01-25 08:57:01 【问题描述】:

我需要将图像上传到 NodeJS 服务器到某个目录。我正在为此使用connect-busboy 节点模块。

我使用以下代码将图像的 dataURL 转换为 blob:

dataURLToBlob: function(dataURL) 
    var BASE64_MARKER = ';base64,';
    if (dataURL.indexOf(BASE64_MARKER) == -1) 
        var parts = dataURL.split(',');
        var contentType = parts[0].split(':')[1];
        var raw = decodeURIComponent(parts[1]);
        return new Blob([raw], type: contentType);
    
    var parts = dataURL.split(BASE64_MARKER);
    var contentType = parts[0].split(':')[1];
    var raw = window.atob(parts[1]);
    var rawLength = raw.length;
    var uInt8Array = new Uint8Array(rawLength);
    for (var i = 0; i < rawLength; ++i) 
        uInt8Array[i] = raw.charCodeAt(i);
    
    return new Blob([uInt8Array], type: contentType);

我需要一种将 blob 转换为文件以上传图像的方法。

有人可以帮我吗?

【问题讨论】:

文件是 Blob,只需添加元属性即可。 上传 blob 时的默认值为 blob。因此,我首先提取了我正在裁剪的文件的名称,然后给出了相同的filename,因此在将裁剪后的文件上传到服务器时通过执行form.append("blob",blob, filename); @skip 我在下面的回答有帮助吗?是这样,请标记为正确答案。 【参考方案1】:

您可以使用 File 构造函数:

var file = new File([myBlob], "name");

根据 w3 规范,这会将 blob 包含的字节附加到新 File 对象的字节中,并创建具有指定名称的文件 http://www.w3.org/TR/FileAPI/#dfn-file

【讨论】:

这就是我要找的,不同的是第一个参数实际上是一个数组,所以我把它用作: var file = new File([myBlob], "name");跨度> 是的。我也在寻找这个解决方案。 Stamplay 服务器无法从 blob 对象中获取文件名。所以我需要将它转换回文件。但是 Safari 不支持文件 API……现在回到 0 :( 文件构造函数不起作用,例如在 PhantomJS 中:TypeError: FileConstructor is not a constructor (evaluating 'new File([''], 'file.pdf', 'size': 1000, 'type': 'application/pdf')') Edge 当前 (2017-10-04) 存在一个错误,该错误会阻止使用此构造函数。 developer.microsoft.com/en-us/microsoft-edge/platform/issues/… 一定要添加文件类型,否则无法正常工作。新文件([myBlob], "name", type: "image/jpeg", );【参考方案2】:

此函数将Blob 转换为File,对我来说非常有用。

原版 JavaScript

function blobToFile(theBlob, fileName)
    //A Blob() is almost a File() - it's just missing the two properties below which we will add
    theBlob.lastModifiedDate = new Date();
    theBlob.name = fileName;
    return theBlob;

TypeScript(使用正确的类型)

public blobToFile = (theBlob: Blob, fileName:string): File => 
    var b: any = theBlob;
    //A Blob() is almost a File() - it's just missing the two properties below which we will add
    b.lastModifiedDate = new Date();
    b.name = fileName;

    //Cast to a File() type
    return <File>theBlob;

用法

var myBlob = new Blob();

//do stuff here to give the blob some data...

var myFile = blobToFile(myBlob, "my-image.png");

【讨论】:

我认为演员应该首先发生,所以你不需要在 TypeScript 中使用any。请参阅this 示例。 这并不适用于所有目的。将此“文件”添加到 ajax 调用将无法正确设置文件名。 这不是一个好的解决方案,生成的对象仍然是一个 blob。 只需添加b.__proto__ = File.prototype,您的解决方案就会成为一个梦想,甚至可以将b instanceOf File 欺骗到true 这不应该是公认的答案,***.com/a/53205768/2557517 或 ***.com/a/31663645/2557517 应该是。【参考方案3】:

Joshua P Nixon 的回答是正确的,但我也必须设置最后修改日期。所以这里是代码。

var file = new File([blob], "file_name", lastModified: 1534584790000);

1534584790000 是“GMT:2018 年 8 月 18 日星期六上午 9:33:10”的 unix 时间戳

【讨论】:

不破坏instanceof的点数喜欢接受的答案 旁注,如果有人这样做并且不想硬编码它最后一次修改是在 2018 年 8 月,您可以随时输入lastModified: Date.now(),这将以毫秒为单位返回当前时间! (就像给出的示例是 2018 年 8 月 18 日 9:33:10 毫秒)【参考方案4】:

打字稿

public blobToFile = (theBlob: Blob, fileName:string): File =>        
    return new File([theBlob], fileName,  lastModified: new Date().getTime(), type: theBlob.type )

Javascript

function blobToFile(theBlob, fileName)       
    return new File([theBlob], fileName,  lastModified: new Date().getTime(), type: theBlob.type )

输出

File name: "fileName", lastModified: 1597081051454, lastModifiedDate: Mon Aug 10 2020 19:37:31 GMT+0200 (Eastern European Standard Time), webkitRelativePath: "", size: 601887, …
lastModified: 1597081051454
lastModifiedDate: Mon Aug 10 2020 19:37:31 GMT+0200 (Eastern European Standard Time) 
name: "fileName"
size: 601887
type: "image/png"
webkitRelativePath: ""
__proto__: File

【讨论】:

【参考方案5】:

为了工作,我必须明确提供类型,尽管它包含在 blob 中:

const file = new File([blob], 'untitled',  type: blob.type )

【讨论】:

【参考方案6】:

我的现代变体:

function blob2file(blobData) 
  const fd = new FormData();
  fd.set('a', blobData);
  return fd.get('a');

【讨论】:

要将文件名添加到生成的文件中,请使用:fd.set('a', blobData, 'filename') fd.set时在某些ios设备上失败 我必须添加带有扩展名的文件名才能使其正常工作。喜欢:fd.set('a', blobData, 'filename.jpg')【参考方案7】:

这个问题困扰了我好几个小时。 我正在使用 Nextjs 并尝试将 canvas 转换为 图像文件

我使用了其他人的解决方案,但创建的文件是

因此,如果这是您的问题,您应该在文件对象中提及 size 属性。

new File([Blob], `my_image$new Date().jpeg`, 
  type: "image/jpeg",
  lastModified: new Date(),
  size: 2,
);

只需将不重要的值添加到键即可。

【讨论】:

大小不是一个有效的选项【参考方案8】:

我已使用FileSaver.js 将 blob 保存为文件。

这是回购:https://github.com/eligrey/FileSaver.js/

用法:

import  saveAs  from 'file-saver';

var blob = new Blob(["Hello, world!"], type: "text/plain;charset=utf-8");
saveAs(blob, "hello world.txt");

saveAs("https://httpbin.org/image", "image.jpg");

【讨论】:

这不能回答问题 他要求转换文件而不是保存文件

以上是关于如何在 JavaScript 中将 Blob 转换为文件的主要内容,如果未能解决你的问题,请参考以下文章

在 javascript 中将 Blob 转换为文件列表

如何在颤动中将 Blob 转换为图像

我想在 Objective-c 中将 base64 转换为 blob

如何在硒 c# 中将 Blob 图像转换为位图图像

如何在 MySQL 中将 BLOB 转换为 TEXT?

如何在 Azure 逻辑应用中将 blob 文件内容转换为 .docx