109

My page generates a URL like this: "blob:http%3A//localhost%3A8383/568233a1-8b13-48b3-84d5-cca045ae384f" How can I convert it to a normal address?

I'm using it as an <img>'s src attribute.

Jeremy
  • 1
  • 77
  • 324
  • 346
Jacob
  • 5,004
  • 18
  • 67
  • 130
  • 1
    even after decoding the URL, it's still a `localhost` link. Find out its public link instead. (which CDN are you using?) – Raptor Feb 19 '13 at 07:33
  • I am wishing to use javascript. – Jacob Feb 19 '13 at 07:38
  • Use the [stackvoverflow link](http://stackoverflow.com/questions/332872/how-to-encode-a-url-in-javascript) .. and [W3C](http://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_decodeuricomponent) Your real problem will be how to make it independent of environment you deploy your code in – user1428716 Feb 19 '13 at 07:42
  • Is there a way to find the public URL from the blob adress. Thhis is the only value I have. – Jacob Feb 19 '13 at 07:43
  • Also http://superuser.com/q/948738/78897 – Pacerier Feb 06 '17 at 21:58
  • https://codepen.io/vidhill/pen/bNPEmX – P Satish Patro Apr 23 '19 at 06:57

6 Answers6

182

A URL that was created from a JavaScript Blob can not be converted to a "normal" URL.

A blob: URL does not refer to data the exists on the server, it refers to data that your browser currently has in memory, for the current page. It will not be available on other pages, it will not be available in other browsers, and it will not be available from other computers.

Therefore it does not make sense, in general, to convert a Blob URL to a "normal" URL. If you wanted an ordinary URL, you would have to send the data from the browser to a server and have the server make it available like an ordinary file.

It is possible convert a blob: URL into a data: URL, at least in Chrome. You can use an AJAX request to "fetch" the data from the blob: URL (even though it's really just pulling it out of your browser's memory, not making an HTTP request).

Here's an example:

var blob = new Blob(["Hello, world!"], { type: 'text/plain' });
var blobUrl = URL.createObjectURL(blob);

var xhr = new XMLHttpRequest;
xhr.responseType = 'blob';

xhr.onload = function() {
   var recoveredBlob = xhr.response;

   var reader = new FileReader;

   reader.onload = function() {
     var blobAsDataUrl = reader.result;
     window.location = blobAsDataUrl;
   };

   reader.readAsDataURL(recoveredBlob);
};

xhr.open('GET', blobUrl);
xhr.send();

data: URLs are probably not what you mean by "normal" and can be problematically large. However they do work like normal URLs in that they can be shared; they're not specific to the current browser or session.

Solomon Ucko
  • 2,682
  • 2
  • 14
  • 27
Jeremy
  • 1
  • 77
  • 324
  • 346
  • 16
    If blob urls don't point to server data, then how come Youtube videos' src url look like: src="blob:https%3A//www.youtube.com/44f26667-03f1-4978-9eed-af0cbf11dd67" (in Chrome) – bhh1988 Sep 03 '14 at 15:53
  • 6
    @bhh1988 That's a very interesting find. I'm not sure what's going on there. If I try to retrieve their src blob URL using an XMLHttpRequest, as described in this post, no content is returned. My guess is that either (a) they generated any empty Blob URL to use as a placeholder while feeding in data from another source or (b) the Blob somehow acts as a proxy for encrypted data (via HTML5 Encrypted Media Extensions). However, I'm not sure how either of these could actually be done in practice. – Jeremy Sep 03 '14 at 16:11
  • 21
    @bhh1988 It looks like the [media source extensions spec](https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html) allows blob URLs to be created for media streams being managed by JavaScript. These do not correspond to static data like the blob URLs discussed in this post, hence the difference in behavior, but they still refer to local information, not directly to data on a server. – Jeremy Sep 11 '14 at 01:33
  • 1
    Hmm, sounds right. It's confusing because the url looks real and intentful, but if it's just a placeholder it shouldn't matter what the value of src is. – bhh1988 Sep 11 '14 at 06:37
  • 3
    I get a `Not allowed to navigate top frame to data URL: data:text/plain;base64,...` error. I get the data, but the `window.location` it is not allowed... – loretoparisi Apr 24 '18 at 14:22
  • I know this question is old, but you can use `puppeteer` to capture the true media calls in-flight and then assemble it's chunks to a file. Takes a bit of byte and stream manipulation, but it's doable. – Felype Aug 09 '19 at 16:52
  • I am using this in Electron.js environment. worked for me too. – NamNamNam Jan 19 '20 at 03:01
  • Each blob has to be created from something. So it should be possible to examine javascript that is launched on page load to see from what it generates. – Sebastian Feb 04 '21 at 23:35
15

another way to create a data url from blob url may be using canvas.

var canvas = document.createElement("canvas")
var context = canvas.getContext("2d")
context.drawImage(img, 0, 0) // i assume that img.src is your blob url
var dataurl = canvas.toDataURL("your prefer type", your prefer quality)

as what i saw in mdn, canvas.toDataURL is supported well by browsers. (except ie<9, always ie<9)

Leooonard
  • 159
  • 1
  • 2
8

For those who came here looking for a way to download a blob url video / audio, this answer worked for me. In short, you would need to find an *.m3u8 file on the desired web page through Chrome -> Network tab and paste it into a VLC player.

Another guide shows you how to save a stream with the VLC Player.

Gasper J.
  • 159
  • 2
  • 9
1

Found this answer here and wanted to reference it as it appear much cleaner than the accepted answer:

function blobToDataURL(blob, callback) {
  var fileReader = new FileReader();
  fileReader.onload = function(e) {callback(e.target.result);}
  fileReader.readAsDataURL(blob);
}
Sean Bannister
  • 2,625
  • 4
  • 28
  • 41
0

I'm very late to the party.

If you want to download the content you can simply use fetch now

fetch(blobURL)
  .then(res => res.blob())
  .then(blob => /*do what you want with the blob here*/)
Radu Diță
  • 8,910
  • 1
  • 18
  • 27
  • I've been trying to use your code (with some inspiration from https://stackoverflow.com/a/58021822/1035977), but, apparently, `fetch()` _cannot_ get a `blob:https://example.com/123e4567-e89b-12d3-a456-426614174000` URL. I'm investigating further... – Gwyneth Llewelyn May 16 '21 at 00:27
  • @GwynethLlewelyn Have you found any solution? – Ghanshyam Baravaliya May 24 '21 at 05:10
-3

As the previous answer have said, there is no way to decode it back to url, even when you try to see it from the chrome devtools panel, the url may be still encoded as blob.

However, it's possible to get the data, another way to obtain the data is to put it into an anchor and directly download it.

<a href="blob:http://example.com/xxxx-xxxx-xxxx-xxxx" download>download</a>

Insert this to the page containing blob url and click the button, you get the content.

Another way is to intercept the ajax call via a proxy server, then you could view the true image url.

ospider
  • 5,563
  • 1
  • 33
  • 38
  • download. It should work. When it will hit the href, it will rename the blob to abc.txt & download – P Satish Patro Apr 23 '19 at 06:53
  • 3
    Why the downvotes? have you actually tried what I said? – ospider Apr 23 '19 at 06:58
  • I have not downvoted. I came here. And, I thought it will work. I am in support of this a littlebit – P Satish Patro Apr 23 '19 at 07:00
  • 2
    Not sure about the downvotes, but this certainly sounds a straightforward way. (With that said, I always get `Failed - Network error` in Chrome 83.0.4103.97 on Linux.) – toraritte Oct 04 '20 at 14:48
  • Quite interesting. I've opened DevTools and added a bit of HTML with that link. It certainly does 'something': it shows up on the page, sure, and you can click to download it — but, like @toraritte said, I also get a `Failed - Network error`. – Gwyneth Llewelyn May 15 '21 at 20:29