How to get a file or blob from an object URL?
Solution 1
Modern solution:
let blob = await fetch(url).then(r => r.blob());
The url can be an object url or a normal url.
Solution 2
As gengkev alludes to in his comment above, it looks like the best/only way to do this is with an async xhr2 call:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'blob:http%3A//your.blob.url.here', true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
if (this.status == 200) {
var myBlob = this.response;
// myBlob is now the blob that the object URL pointed to.
}
};
xhr.send();
Update (2018): For situations where ES5 can safely be used, Joe has a simpler ES5-based answer below.
Solution 3
Maybe someone finds this useful when working with React/Node/Axios. I used this for my Cloudinary image upload feature with react-dropzone
on the UI.
axios({
method: 'get',
url: file[0].preview, // blob url eg. blob:http://127.0.0.1:8000/e89c5d87-a634-4540-974c-30dc476825cc
responseType: 'blob'
}).then(function(response){
var reader = new FileReader();
reader.readAsDataURL(response.data);
reader.onloadend = function() {
var base64data = reader.result;
self.props.onMainImageDrop(base64data)
}
})
Solution 4
Using fetch for example like below:
fetch(<"yoururl">, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + <your access token if need>
},
})
.then((response) => response.blob())
.then((blob) => {
// 2. Create blob link to download
const url = window.URL.createObjectURL(new Blob([blob]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', `sample.xlsx`);
// 3. Append to html page
document.body.appendChild(link);
// 4. Force download
link.click();
// 5. Clean up and remove the link
link.parentNode.removeChild(link);
})
You can paste in on Chrome console to test. the file with download with 'sample.xlsx' Hope it can help!
Solution 5
The problem with fetching the blob URL again is that this will create a full copy of the Blob's data, and so instead of having it only once in memory, you'll have it twice. With big Blobs this can blow your memory usage quite quickly.
It's rather unfortunate that the File API doesn't give us access to the currently linked Blobs, certainly they thought web-authors should store that Blob themselves at creation time anyway, which is true:
The best here is to store the object you used when creating the blob:// URL.
If you are afraid this would prevent the Blob from being Garbage Collected, you're right, but so does the blob:// URL in the first place, until you revoke it. So holding yourself a pointer to that Blob won't change a thing.
But for those who aren't responsible for the creation of the blob:// URI (e.g because a library made it), we can still fill that API hole ourselves by overriding the default URL.createObjectURL and URL.revokeObjectURL methods so that they do store references to the object passed.
Be sure to call this function before the code that does generate the blob:// URI is called.
// Adds an URL.getFromObjectURL( <blob:// URI> ) method
// returns the original object (<Blob> or <MediaSource>) the URI points to or null
(() => {
// overrides URL methods to be able to retrieve the original blobs later on
const old_create = URL.createObjectURL;
const old_revoke = URL.revokeObjectURL;
Object.defineProperty(URL, 'createObjectURL', {
get: () => storeAndCreate
});
Object.defineProperty(URL, 'revokeObjectURL', {
get: () => forgetAndRevoke
});
Object.defineProperty(URL, 'getFromObjectURL', {
get: () => getBlob
});
const dict = {};
function storeAndCreate(blob) {
const url = old_create(blob); // let it throw if it has to
dict[url] = blob;
return url
}
function forgetAndRevoke(url) {
old_revoke(url);
try {
if(new URL(url).protocol === 'blob:') {
delete dict[url];
}
} catch(e){}
}
function getBlob(url) {
return dict[url] || null;
}
})();
// Usage:
const blob = new Blob( ["foo"] );
const url = URL.createObjectURL( blob );
console.log( url );
const retrieved = URL.getFromObjectURL( url );
console.log( "retrieved Blob is Same Object?", retrieved === blob );
fetch( url ).then( (resp) => resp.blob() )
.then( (fetched) => console.log( "fetched Blob is Same Object?", fetched === blob ) );
And an other advantage is that it can even retrieve MediaSource objects, while the fetching solutions would just err in that case.
Related videos on Youtube

BrianFreud
Updated on October 07, 2021Comments
-
BrianFreud over 1 year
I am allowing the user to load images into a page via drag&drop and other methods. When an image is dropped, I'm using
URL.createObjectURL
to convert to an object URL to display the image. I am not revoking the url, as I do reuse it.So, when it comes time to create a
FormData
object so I can allow them to upload a form with one of those images in it, is there some way I can then reverse that Object URL back into aBlob
orFile
so I can then append it to aFormData
object?-
gengkev almost 11 yearsnevermind about the previous two comments - all you need to do is send an
XMLHttpRequest
to the blob URL. -
user764754 over 6 yearsWhy not simply store the original file objects somewhere, then use the object URL to display them and on form submit use the original files?
-
Malcolm Salvador almost 6 years@user764754 because trying to get the URL of the file being uploaded by the user displays as "C:\fakepath"
-
Armen Michaeli about 2 yearsThis is a XY problem. A script obtains references to one or multiple files as these are dropped onto a page. You only need to create URLs for these in order to create links for these for the user to use (look at what they dragged, f.e.), but for including the file(s) with submission of a form, you need to add them one way or another -- whether gotten back from URLs or the original objects. You can look at the
DataTransfer
class to reset your file input control, otherwise your form is almost useless anyway (you can forego it for script-assisted submission).
-
-
BrianFreud over 8 yearsWhen would you ever have a objectURL which is not local to the current domain and scope?
-
albert yu over 8 yearsi did it same as above, but got 404 not found with the xhr. what's going on?
-
mraxus about 7 yearsPlease note that some browsers (read old IE...), if you need to handle those see post stackoverflow.com/questions/17657184/…
-
Rahul Bali almost 7 yearsCan I save this file to the local file system?
-
BrianFreud almost 7 yearsNote that that's not actually giving you back the same original file; it's making a new image file on the fly. When I last tested that a couple years ago, I found that at least in Chrome, the new image file isn't compressed at all - I had 10k jpgs turning into 2.5 mb jpgs.
-
Wagner Bertolini Junior over 6 years@BrianFreud "When would you ever have a objectURL which is not local to the current domain and scope?" In my case I am trying to give a Amazon S3 blob a different filename, that is currently a "guid" on the S3 without extension. So, in my case I am using a cross-domain call.
-
BrianFreud over 6 yearsObjectURLs are by definition local. Object URLs are URLs that point to files on disk. Given that there is no such thing as a cross-domain objectURL, you're combing two different concepts, thus your problem using the given solution.
-
BrianFreud over 6 years"Object URLs are URLs that point to files on disk." ObjectURLs by definition can only be local.
-
Wagner Bertolini Junior over 6 years@BrianFreud I got it that is not exactly the answer of this question. But I still think that its a good answer to leave since I got here looking for the answer of a little different question 'How to get a file or blob from an URL?'. If you check you own answer, there are 10 upvotes on 'It doesn't work in case of cross domain requests. '. So more than 10 persons got here looking for that. I decided then to leave it here.
-
BrianFreud over 6 yearsProblem is, your answer knowingly doesn't answer this question. A normal URL and an object URL are two entirely different things. Regarding the # of upvotes on "It doesn't work in case of cross domain requests.", wouldn't you think it better explain why that's literally impossible here, and to point to somewhere that does show the answer for normal URLs, rather than confusing things here by conflating normal URLs and object URLs?
-
Wagner Bertolini Junior over 6 years@BrianFreud feel free to suggest an edit on my answer. I will study about the subject, maybe I misunderstood what is an "objectURL" vs an "object URL"... English is not my native. I will make a research about the subject to give a better answer. But I think that are others that come here looking for something different. I did not search for "objectURL" to get here, that was my point before. But I got you too.
-
Arihant about 5 yearsDoes this work for cross domain requests? Twitter videos have blob URL. I need to be able to gather the blob object that blob URL is pointing to. I'm using fetch api in the browser, which is giving me this error –
Refused to connect to 'blob:https://twitter.com/9e00aec3-6729-42fb-b5a7-01f50be302fa' because it violates the following Content Security Policy directive: "connect-src
. Could you have a hint what might I might be doing wrong / not getting? -
dbakiu over 4 yearsAnd if you want to directly get a file from the promise, you can generate a file as follows.
let file = await fetch(url).then(r => r.blob()).then(blobFile => new File([blobFile], "fileNameGoesHere", { type: "image/png" })
-
waldgeist almost 4 yearsUnfortunately, this solution does not work for me in Chrome. The browser fails to load this URL.
-
Abhishek Ghosh over 3 yearsI think the OP asked about converting a blob url to actual file/blob, rather than the other way around.
-
Noah Stahl about 3 yearsI was able to use this one-liner to get the result with the blob as data property: const result = await axios.get(url, { responseType: "blob" });
-
therightstuff about 3 yearscombined with stackoverflow.com/a/18650249/2860309 for reading into base64, this really helped!
-
Matt Fletcher about 3 yearsWaldgeist, did you wrap it in the createObjectUrl()?
-
Nawin over 2 yearshow can I use this when multiple urls need to pass
-
Nawin over 2 yearsHow can we write this as as simple utility function like passing url and getting file anyone
-
mxcl almost 2 yearsThere is no “Joe” below.
-
BrianFreud almost 2 yearsGood call. If I remember correctly, those URL methods did not exist back when I first asked this question.
-
Kaiido almost 2 years@BrianFreud they still don't exist, we have to implement it ourselves (well I did so now you just have to include that script before URL.createObjectURL is called).
-
yavorbel over 1 year
let file = await fetch(url).then(r => r.blob()).then(blobFile => new File([blobFile], "fileNameGoesHere", { type: "image/png" }))
. There was a missing bracket at the end -
Crashalot about 1 yearThanks for this answer! Do you have a Patreon where people can support your work?