如何在JavaScript中实例化一个文件对象?

201

JavaScript中有一个 File 对象, 我想为测试目的实例化一个。

我已经尝试使用 new File(),但是我得到了一个“非法构造函数”的错误。

是否有可能创建一个File对象?


参考 File 对象 : https://developer.mozilla.org/zh-CN/docs/Web/API/File


MDN链接已更改:https://developer.mozilla.org/zh-CN/docs/Web/API/File - kca
6个回答

268
根据W3C文件API规范,File构造函数需要2个(或3个)参数。因此,要创建一个空文件,请执行以下操作:
var f = new File([""], "filename");
  • 第一个参数是以文本行数组提供的数据;
  • 第二个参数是文件名;
  • 第三个参数看起来像:

var f = new File([""], "filename.txt", {type: "text/plain", lastModified: date})

它能在FireFox、Chrome和Opera中工作,但无法在Safari或IE/Edge中工作。


2
在Chrome 37 / Ubuntu上会产生“非法构造函数”错误,因此它无法工作。 - Sebastien Lorber
2
这在Firefox 28+、Chrome 38+和Opera 25+中可以正常工作。然而,Safari和IE至今仍未实现此构造函数(见http://caniuse.com/#feat=fileapi)。我目前正在寻找一个polyfill或一种模拟它的方法,但是迄今为止还没有找到合适的解决方案。 - Pierre-Adrien
@PA.Buisson 我不确定这是否适用于所有情况(对我来说已经足够了),但是您可以使用Blob()构造函数,如此处所建议的。 - raymondboswel
2
这在Windows Edge中有什么替代方案? - Raviranjan Mishra
7
对于IE11,您可以使用Blob类来构造File对象。在我看来,这似乎是最具可移植性的解决方案。file = new Blob([blobdata], {type: filetype, lastModified: filelastModified}); file.name = filename - Jesse Hogan
显示剩余4条评论

37

现在你可以了!

var parts = [
  new Blob(['you construct a file...'], {type: 'text/plain'}),
  ' Same way as you do with blob',
  new Uint16Array([33])
];

// Construct a file
var file = new File(parts, 'sample.txt', {
    lastModified: new Date(0), // optional - default = now
    type: "overide/mimetype" // optional - default = ''
});

var fr = new FileReader();

fr.onload = function(evt){
   document.body.innerHTML = evt.target.result + "<br><a href="+URL.createObjectURL(file)+" download=" + file.name + ">Download " + file.name + "</a><br>type: "+file.type+"<br>last modified: "+ file.lastModifiedDate
}

fr.readAsText(file);


不,它在Chrome中不起作用。请参见https://code.google.com/p/chromium/issues/detail?id=164933。验证了它在Chrome 36 OSX中不起作用。 - Ray Nicholus
然后,我会验证当您运行new File([], '')时,它在Chrome 35 OSX中可以正常工作。 - Endless
刚刚测试了一下,在35版本中也不起作用。请调整您的答案以反映这只在Firefox中有效。 - Ray Nicholus
嗯,你说得对。这只是因为我激活了一个实验性的Chrome标志,所以它才对我起作用... https://dl.dropboxusercontent.com/u/3464804/jCmQr8vrGk.gif - Endless
在Chrome 37 / Ubuntu上会产生“非法构造函数”错误。 - Sebastien Lorber
对我来说,在Chrome 45中工作。 - ccnokes

19

更新

BlobBuilder已被弃用,如果你正在用它进行测试,请看看是否可以使用其他方法。

否则,可以采用下面的迁移策略,使用Blob代替,例如这个问题的答案。

使用Blob替代

作为一种替代方案,可以使用Blob来代替File,因为根据W3C规范,File接口是从Blob继承而来的:

interface File : Blob {
    readonly attribute DOMString name;
    readonly attribute Date lastModifiedDate;
};

基于Blob的File接口,继承了Blob的功能并扩展以支持用户系统中的文件。

创建Blob

使用BlobBuilder可以将一个Blob提供给现有的JavaScript方法,该方法通过XMLHttpRequest上传File,像这样就可以正常工作:

var BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder;
var bb = new BlobBuilder();

var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://jsfiddle.net/img/logo.png', true);

xhr.responseType = 'arraybuffer';

bb.append(this.response); // Note: not xhr.responseText

//at this point you have the equivalent of: new File()
var blob = bb.getBlob('image/png');

/* more setup code */
xhr.send(blob);

扩展示例

这个示例的其余部分可以在jsFiddle上找到,以更完整的形式呈现,但无法成功上传,因为我不能长期地暴露上传逻辑。


11
这条评论已经过时了,请勿使用BlobBuilder,而是使用Blob构造器。例如:Blob(['mythingy'], { type: "thingy" })。 - odinho - Velmont
这段代码无法运行。TypeError:BlobBuilder不是构造函数。 - Pointer Null
2
很遗憾,BlobBuilder已经过时:https://developer.mozilla.org/en-US/docs/Web/API/BlobBuilder - JD.
DataTransferItemList.add 需要 File 而不是 Blob。那么对于最初的问题:如何实例化一个 File - Tomáš Zato

5

7
尽管我很不情愿说这句话,但 Edge 是一个主流浏览器。 - li x
实际上我并没有看到很多人使用它。https://caniuse.com/#feat=fileapi - IE 2.6%,Edge - 1.4%,Opera Mini - 2.7%。在https://netmarketshare.com/browser-market-share.aspx上是4.3%。如果您关心Edge,那么需要找到一些解决方法https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/9551546/。 - Pavel Evstigneev
Evestigneev,你误解了结果,因为支持的浏览器全球使用率约为0.2%。这个数字是使用API的浏览器数量,而Edge / IE本身占仍在使用中的浏览器的约15%。 - li x

2
在JavaScript中为已经存在于DOM中的图片创建一个文件对象(API)的想法是:
<img src="../img/Products/fijRKjhudDjiokDhg1524164151.jpg">

var file = new File(['fijRKjhudDjiokDhg1524164151'],
                     '../img/Products/fijRKjhudDjiokDhg1524164151.jpg', 
                     {type:'image/jpg'});

// created object file
console.log(file);

请不要这样做!……(但我还是做了)

-> 控制台会给出一个类似于对象文件的结果:

File(0) {name: "fijRKjokDhgfsKtG1527053050.jpg", lastModified: 1527053530715, lastModifiedDate: Wed May 23 2018 07:32:10 GMT+0200 (Paris, Madrid (heure d’été)), webkitRelativePath: "", size: 0, }
lastModified:1527053530715
lastModifiedDate:Wed May 23 2018 07:32:10 GMT+0200 (Paris, Madrid (heure d’été)) {}
name:"fijRKjokDhgfsKtG1527053050.jpg"
size:0
type:"image/jpg"
webkitRelativePath:""__proto__:File

但对象的大小不正确...

为什么我需要这样做?

例如,在产品更新期间重新传输已上传的图像,以及在更新过程中添加的其他图像。


-4
由于这是JavaScript和动态的,您可以定义与文件接口匹配的自己的类,并使用该类代替。
我不得不在dropzone.js中这样做,因为我想模拟文件上传并且它适用于文件对象。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接