Why use `URL.createObjectURL(blob)` instead of `image.src`?
Asked Answered
S

1

16

Q1. In the context of asynchronous JavaScript and the need to ‘fetch’ data from the client-side, why can’t we just edit our image elements by its attribute src?

Q2. Why is the Blob conversion process necessary to go through?

Q3. What is the blob role?

e.g. Retrieving image file from JSON. (BTW, I extracted it from MDN webpage, mind the comments)


  function fetchBlob(product) {
    // construct the URL path to the image file from the product.image property
    let url = 'images/' + product.image;
    // Use fetch to fetch the image, and convert the resulting response to a blob
    // Again, if any errors occur we report them in the console.
    fetch(url).then(function(response) {
        return response.blob();
    }).then(function(blob) {
      // Convert the blob to an object URL — this is basically an temporary internal URL
      // that points to an object stored inside the browser
      let objectURL = URL.createObjectURL(blob);
      // invoke showProduct
      showProduct(objectURL, product);
    });
  }

Simulant answered 19/4, 2020 at 9:29 Comment(2)
You can. And you’re right, for this scenario it’s totally useless. The code is just meant for illustrating how to use createObjectURL API.Asmara
But createObjectURL can be useful for some other cases beyond image. Say you make a web app which allows your user to drag and drop an arbitrary file, then compress it and provide a download link for the zip file. It can be done at client side with pure js, no server involved. For this case createObjectURL would be a meaningful part.Asmara
I
20

If you can, then use the url directly as the srcof your <img>.

Using a blob: URL is only useful if you have a Blob holding the image file, and you need to display it.

One common case where this happens is when you allow your users to pick a file from their disk. The file picker will give you access to a File object, which is a Blob, and which you can load in memory. However, you don't have access to an URI that points to the file on disk, so you can't set the src in that case.
Here you need to create a blob: URI which will point to the File object. The browser internal fetching mechanism will be able to retrieve the data on user's disk from this URL and thus to display that image:

document.querySelector('input').onchange = e => {
  const file = e.target.files[0]; // this Object holds a reference to the file on disk
  const url = URL.createObjectURL(file); // this points to the File object we just created
  document.querySelector('img').src = url;
};
<input type="file" accepts="image/*">
<img>

Other cases imply that you did create the image file from the front-end (e.g using a canvas).

But if your Blob is only the result of fetching the resource from your server, and that your server doesn't require a special request to serve it, then indeed, there is no real point...

Ison answered 19/4, 2020 at 10:26 Comment(15)
URL.createObjectURL has been deprecated and it throws an exception on Chrome.Err
@Err only URL.createObjectURL (mediaStream) has been deprecated and you could never use at the src of an img...Ison
I am a bit confused then: developer.mozilla.org/en-US/docs/Web/API/File/…. Maybe I am using just a wrong namespace/package then (with same name though). In the example the uploaded File is used as src value after being passed to URL.createObjectURLErr
@Err I guess you are yes, and I'm not sure to follow what you describe. Once again, what has been deprecated is to pass a MediaStream to createObjectURL (e.g one you'd get with getUserMedia(). Passing a File or a Blob or even a MediaSource is still very supported everywhere, but it ever made sense to set the resulting blob: URI as an <img>'s src only when that blob: URI is pointing to an image file (i.e when it was created using a Blob or a File)Ison
Thanks @Kaiido, my confusion came from the fact that many of these blogs (even MDN) are very recent, therefore I would have expected to avoid promoting a deprecated method. That said, if I have a Blob that refers to an image, how can I use or convert it to be displayed in a src attribute?Err
@Err No you don't get it... Using it with a Blob or a File is still supported everywhere, that's what you should be using and that's even what this answer is promoting. What has been deprecated is something else entirely, just forget about, let's say nothing has been deprecated, you can still use URL.createObjectURL.Ison
Ok, thanks for clarifying that out. Then I have to find out why in Chrome (android) I get the error "Failed to execute createObjectURL on URL: no function was found that matched the signature provided".Err
@Err You mean from the answer's snippet?Ison
yes. I use similar code in a project of mine. I have already a Blob targeting an image, instead of letting the he user upload it. Other than that the code is the same. But when the page loads, I get the exception as in the previous comment.Err
Log what you pass to that method, I bet it's not what you think.Ison
I get blob:https://my-domain/1234-2323-..... The image comes from the device contact list (as in demo glitch.com/edit/#!/contact-picker?path=demo.js%3A88%3A49 - line 88). In that demo, the image is displayed correctly and the URL is without blog prefix, just 1234-2323-...bin, but I use the same method.Err
It's already a blob: URI then. Passing a string in this method will throw. Can't help more, you may want to open a question if you can't find where the issue comes from yourselfIson
I am able to receive the Images with this method but If I run Continuous receiving images it will generate error. internal/process/next_tick.js:103 GET blob:file:///cd179234-2ae4-477e-ad31-6e631476506c 404 (Not Found)Rotatory
@AmarnathReddySurapureddy you're on node.js, right? I'm sorry, this answer was specifically about browsers, I'm not sure how node's implementation works, nor if it's any advisable to use it there.Ison
Thanks for response. I got solution for question data.src="data:image/png;base64,"+ image ; It will show image on UI.Rotatory

© 2022 - 2024 — McMap. All rights reserved.