285

I need to upload an image to NodeJS server to some directory. I am using connect-busboy node module for that.

I had the dataURL of the image that I converted to blob using the following code:

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

I need a way to convert the blob to a file to upload the image.

Could somebody help me with it?

3
  • 4
    Files are Blobs, just tack on the meta properties and you're good to go. Commented Nov 26, 2014 at 21:59
  • 1
    The default for a blob when uploading it is blob. So, I first extracted the name of the file I was cropping and then gave the same filename so the cropped file while uploading it to server by doing form.append("blob",blob, filename);. Commented Nov 26, 2014 at 23:21
  • @skip did my answer below help out? Is so, please mark it as the correct answer. Commented May 14, 2015 at 14:22

9 Answers 9

465

You can use the File constructor:

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

As per the w3 specification this will append the bytes that the blob contains to the bytes for the new File object, and create the file with the specified name http://www.w3.org/TR/FileAPI/#dfn-file

Sign up to request clarification or add additional context in comments.

11 Comments

This is what I was looking for, the one difference is the first argument is actually an array so I used it as: var file = new File([myBlob], "name");
Yes. I am looking for this solution too. Stamplay server can not get the file name from blob object. So I need to convert it back to file. But Safari do not support file API... back to 0 now :(
File constructors do not work e.g. in PhantomJS: TypeError: FileConstructor is not a constructor (evaluating 'new File([''], 'file.pdf', {'size': 1000, 'type': 'application/pdf'})')
Edge has currently (2017-10-04) a bug that prevents the usage of this constructor. developer.microsoft.com/en-us/microsoft-edge/platform/issues/…
Be sure to add file type, otherwise it will not work properly. new File([myBlob], "name", { type: "image/jpeg", });
|
225

This function converts a Blob into a File and it works great for me.

Vanilla 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 (with proper typings)

public blobToFile = (theBlob: Blob, fileName:string): File => {
  const 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 theBlob as File;
}

Usage

const myBlob = new Blob();

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

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

11 Comments

I think the cast should happen first so you don't need to use any in TypeScript. See this example.
This does not work for all purposes. Adding this "File" to an ajax call will not set the filename correctly.
This is not a good solution, the produced object still a blob.
Just add b.__proto__ = File.prototype, and your solution becomes a dream that even tricks b instanceOf File to true
This should not be the accepted answer, stackoverflow.com/a/53205768/2557517 or stackoverflow.com/a/31663645/2557517 should be.
|
74

Joshua P Nixon's answer is correct but I had to set last modified date also. so here is the code.

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

1534584790000 is an unix timestamp for "GMT: Saturday, August 18, 2018 9:33:10 AM"

2 Comments

Points for not breaking instanceof like the accepted answer
side note, if anyone is doing this and doesn't want to hard code that it was last modified in august 2018, you can always put lastModified: Date.now() and that'll return the current time in milliseconds! (just like how the example given is august 18 2018 at 9:33:10 in milliseconds)
44

Typescript

public blobToFile = (theBlob: Blob, fileName:string): File => {       
    return new File(
        [theBlob as any], // cast as any
        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 })
}

Output

screenshot

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

Comments

32

For me to work I had to explicitly provide the type although it is contained in the blob by doing so:

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

Comments

22

My modern variant:

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

3 Comments

To add a filename to the resulting file use: fd.set('a', blobData, 'filename')
It fails in some IOS device when fd.set
I had to add the file name with the extension to make it work right. Like: fd.set('a', blobData, 'filename.jpg')
10
var blob = new Blob(["Hello, world!"], { type: "text/plain;charset=utf-8" });

var file = new File([blob], "name.txt");

Now you can upload as .txt file

Comments

2

This problem was bugging me for hours. I was using Nextjs and trying to convert canvas to an image file.

I used the other guy's solution but the created file was empty.

So if this is your problem you should mention the size property in the file object.

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

Just add the key the value it's not important.

3 Comments

size isn't a valid option
Not working bro !! , Blob is actually the object right ?
Thanks for me it worked, size is must
-4

I have used FileSaver.js to save the blob as file.

This is the repo : https://github.com/eligrey/FileSaver.js/

Usage:

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

2 Comments

this dose not answer the question
he asked to convert a file not save a file

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.