197

There's a File object in JavaScript. I want to instantiate one for testing purposes.

I have tried new File(), but I get an "Illegal constructor" error.

Is it possible to create a File object ?


File Object reference : https://developer.mozilla.org/en/DOM/File

Matt Hulse
  • 5,496
  • 4
  • 29
  • 37
julesbou
  • 5,570
  • 4
  • 31
  • 36

6 Answers6

265

According to the W3C File API specification, the File constructor requires 2 (or 3) parameters.

So to create a empty file do:

var f = new File([""], "filename");
  • The first argument is the data provided as an array of lines of text;
  • The second argument is the filename ;
  • The third argument looks like:

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

It works in FireFox, Chrome and Opera, but not in Safari or IE/Edge.

Zakaria
  • 14,892
  • 22
  • 84
  • 125
AlainD
  • 6,187
  • 3
  • 17
  • 31
  • 2
    Produces `Illegal constructor` on Chrome 37 / Ubuntu so no it does not work – Sebastien Lorber Feb 12 '15 at 19:09
  • 2
    This does work in Firefox 28+, Chrome 38+ and Opera 25+.However, Safari and IE still do not implement this constructor today (see http://caniuse.com/#feat=fileapi). I'm currently looking for a polyfill or a way to emulate this, but did'nt find any suitable solution so far. – Pierre-Adrien May 13 '15 at 16:17
  • @PA.Buisson I'm not sure if this holds for all cases(it was sufficient for me), but you can use the Blob() constructor instead, as suggested [here](https://developer.microsoft.com/en-us/microsoft-edge/platform/documentation/dev-guide/html5/file-api/) – raymondboswel Jan 23 '17 at 10:07
  • 2
    What is alternative of this for windows edge? – Raviranjan Mishra Jul 24 '17 at 09:43
  • Works in Safari as of Jun 19, 2018. version: Safari 11.1.1. – rahul Jun 19 '18 at 10:40
  • How do you do this in nodeJS? – Malcolm Salvador Jul 26 '18 at 21:18
  • 7
    For IE11, you can use the Blob class to construct a File object. This seems to be the most portable solution to me. `file = new Blob([blobdata], {type: filetype, lastModified: filelastModified}); file.name = filename` – Jesse Hogan Apr 09 '19 at 17:13
  • Does anyone know, how to get the path of the file?. – Praveenkumar Beedanal May 06 '19 at 12:31
  • I had to do something similar as Jesse Hogan suggested because TypeScript overrides the File class and changes its constructor to one that does not accept a blob. – Wak May 20 '22 at 08:45
36

Now you can!

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);
Endless
  • 34,080
  • 13
  • 108
  • 131
19

Update

BlobBuilder has been obsoleted see how you go using it, if you're using it for testing purposes.

Otherwise apply the below with migration strategies of going to Blob, such as the answers to this question.

Use a Blob instead

As an alternative there is a Blob that you can use in place of File as it is what File interface derives from as per W3C spec:

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

The File interface is based on Blob, inheriting blob functionality and expanding it to support files on the user's system.

Create the Blob

Using the BlobBuilder like this on an existing JavaScript method that takes a File to upload via XMLHttpRequest and supplying a Blob to it works fine like this:

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);

Extended example

The rest of the sample is up on jsFiddle in a more complete fashion but will not successfully upload as I can't expose the upload logic in a long term fashion.

Community
  • 1
  • 1
Nick Josevski
  • 4,156
  • 3
  • 43
  • 63
4

Now it's possible and supported by all major browsers: https://developer.mozilla.org/en-US/docs/Web/API/File/File

var file = new File(["foo"], "foo.txt", {
  type: "text/plain",
});
Pavel Evstigneev
  • 4,918
  • 31
  • 21
  • 7
    As much as it pains me to say this, edge is a major browser. – li x Oct 01 '18 at 13:39
  • I didn't see much people using it actually. https://caniuse.com/#feat=fileapi - IE 2.6%, Edge - 1.4%, Opera Mini - 2.7%. On https://netmarketshare.com/browser-market-share.aspx is 4.3%. If you care about Edge then need to find some workaround https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/9551546/ – Pavel Evstigneev Oct 02 '18 at 08:57
  • Evestigneev you've misinterpreted the results as the supported browsers have a global use of around 0.2%. This figure is how many browsers are using the api while edge / IE itself make up around 15% of browsers still in use. – li x Oct 02 '18 at 09:15
2

The idea ...To create a File object (api) in javaScript for images already present in the DOM :

<img src="../img/Products/fijRKjhudDjiokDhg1524164151.jpg">

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

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

Don't do that ! ... (but I did it anyway)

-> the console give a result similar as an Object 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

But the size of the object is wrong ...

Why i need to do that ?

For example to retransmit an image form already uploaded, during a product update, along with additional images added during the update

-5

Because this is javascript and dynamic you could define your own class that matches the File interface and use that instead.

I had to do just that with dropzone.js because I wanted to simulate a file upload and it works on File objects.

Ian1971
  • 3,666
  • 7
  • 33
  • 61