3

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

hyfyline
  • 33
  • 1
  • 4
  • 1
    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. – hackape Apr 19 '20 at 09:39
  • 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. – hackape Apr 19 '20 at 09:44

2 Answers2

3

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...

Kaiido
  • 87,051
  • 7
  • 143
  • 194
  • URL.createObjectURL has been deprecated and it throws an exception on Chrome. – Francesco Sep 10 '20 at 14:13
  • @Francesco only URL.createObjectURL (mediaStream) has been deprecated and you could never use at the src of an img... – Kaiido Sep 10 '20 at 22:54
  • I am a bit confused then: https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications#Example_Using_object_URLs_to_display_images. 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.createObjectURL – Francesco Sep 11 '20 at 06:26
  • @Francesco 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 '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) – Kaiido Sep 11 '20 at 06:31
  • 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? – Francesco Sep 11 '20 at 06:37
  • @Francesco 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. – Kaiido Sep 11 '20 at 06:40
  • 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". – Francesco Sep 11 '20 at 07:05
  • @Francesco You mean from the answer's snippet? – Kaiido Sep 11 '20 at 07:06
  • 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. – Francesco Sep 11 '20 at 07:22
  • Log what you pass to that method, I bet it's not what you think. – Kaiido Sep 11 '20 at 07:23
  • I get `blob:https://my-domain/1234-2323-....`. The image comes from the device contact list (as in demo https://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. – Francesco Sep 11 '20 at 12:41
  • 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 yourself – Kaiido Sep 11 '20 at 13:07
0

Example of creating a Blob URL:
https://www.w3schools.com/code/tryit.asp?filename=GMLA27XOT9SA


This is an example of a blob URL that was created:

<blob:https://tryit.w3schools.com/c577893f-9510-4a12-a1ce-6a1a101269a2>
Maxime Lafarie
  • 1,618
  • 1
  • 13
  • 33