Attach a blob to an input of type file in a form

I had a similar problem with a fairly complex form in an angular app, so instead of the form I just sent the blob individually using XMLHttpRequest(). This particular "blob" was created in a WebAudioAPI context, creating an audio track in the user's browser.

var xhr = new XMLHttpRequest();
xhr.open('POST', 'someURLForTheUpload', true); //my url had the ID of the item that the blob corresponded to
xhr.responseType = 'Blob';
xhr.setRequestHeader("x-csrf-token",csrf); //if you are doing CSRF stuff
xhr.onload = function(e) { /*irrelevant code*/ };
xhr.send(blob);

It is possible to set value of <input type="file">.

To do this you create File object from blob and new DataTransfer object:

let file = new File([data], "img.jpg",{type:"image/jpeg", lastModified:new Date().getTime()});
let container = new DataTransfer();

Then you add file to container thus populating its 'files' property, which can be assigned to 'files' property of file input:

container.items.add(file);
fileInputElement.files = container.files;

Here is a fiddle with output, showing that file is correctly placed into input. The file is also passed correctly to server on form submit. This works at least on Chrome 88.

If you need to pass multiple files to input you can just call container.items.add multiple times. So you can add files to input by keeping track of them separately and overwriting its 'files' property as long as this input contains only generated files (meaning not selected by user). This can be useful for image preprocessing, generating complex files from several simple ones (e.g. pdf from several images), etc.

API references:

  • File object
  • DataTransfer object