Search code examples
node.jsexpressfilefetch

createObjectURL error: `argument must be an instance of Blob. Received an instance of Blob`


I have an express route which contains the following:

let result = await fetch("http://someurl");
result = await result.blob();
console.log(result)
const img = URL.createObjectURL(result);

This produces the following error (on line 4):

TypeError: The "obj" argument must be an instance of Blob. Received an instance of Blob

What's going on here?

If it helps, the result of the console.log is:

Blob {
  [Symbol(type)]: 'image/png',
  [Symbol(buffer)]: <Buffer 89 50 4e  ... 481501 more bytes>
}

and the fetch route goes to another express app which calls res.sendFile(myfilepath)


Solution

  • The server-side equivalent of:

    let result = await fetch("http://someurl");
    result = await result.blob();
    console.log(result)
    const img = URL.createObjectURL(result);
    

    is

    let result = await fetch("http://someurl");
    result = await result.arrayBuffer();
    console.log(result)
    const img = Buffer.from(result).toString("base64"));
    

    and the image is then rendered client-side with something similar to:

    <img src="data:image/png;base64, <%= img %>">
    

    Using EJS, for this example; the point here being to translate the image data into base-64 encoded text, which can then be rendered using an image data URI (https://css-tricks.com/data-uris/)

    Note that this sort of hoop-jumping is only required when getting the image data requires some sort of server-side authentication, as in most cases you'd just do:

    <img src="http://someurl">
    

    I have the following (cut-down) code where images are accessible only after authenticating:

    export function getImage({ imageUrl, token }) {
      return fetch(`${apiServer}/${imageUrl}`, {
        headers: {
          Authorization: `Bearer ${token}`,
        },
      })
        .then((response) => response.arrayBuffer())
        .then((blob) => Buffer.from(blob).toString("base64"));
    }