0

So, I want to use the very nice https://picsum.photos/ to fetch a few random images and cache them for later user.

If I simply set the src of an image tag with https://picsum.photos/id/493/200/300 - it works fine and dandy, but I wish to cache these images.

The content type of the request is image/jpeg.

I'm using Axios for my requests, so I grab response.data, but I'm not sure what to do next.

I've tried to put many thins in as the src of my img:

  • simply response.data
  • btoa(unescape(encodeURIComponent(response.data)));
  • data:image/jpeg;base64,${btoa(unescape(encodeURIComponent(response.data)))}};

Now I've ran out of ideas.

I guess my first problem is I'm not really sure what is being returned by the service. A byte array of said image? If I do typeof I get string, encoded byte array? Very confusing.

Here you can find the resulting img element: https://pastebin.com/9F0gnC7D

MustSeeMelons
  • 636
  • 1
  • 10
  • 22
  • `image/jpeg;base64` requires data converted to base64. Where are you doing it? But this route seems like [the right one](https://stackoverflow.com/a/9464137/223424). – 9000 Aug 20 '19 at 16:06
  • @9000 I'm converting the data with `btoa`. – MustSeeMelons Aug 20 '19 at 16:22
  • I wonder why you do `unescape(encodeURIComponent(response.data))` and not just `btoa(response.data)`. – 9000 Aug 20 '19 at 16:24
  • 1
    @9000 because of this error: https://stackoverflow.com/questions/23223718/failed-to-execute-btoa-on-window-the-string-to-be-encoded-contains-characte – MustSeeMelons Aug 20 '19 at 16:44
  • Maybe this would be helpful:- https://stackoverflow.com/questions/10240110/how-do-you-cache-an-image-in-javascript – gaurav soni Aug 20 '19 at 17:51

1 Answers1

0

Got it working, the first important bit of information: If there is no Content-Encoding header in the response, it means that the endpoint returns the raw bytes.

The second and last piece: Axios returs a JSON, you can't put binary in JSON, so in the transformation to string it gets mangled, but there is a fix:

    fetchRandomPic: async (): Promise<any> => {
        const response = await Axios.get(URLS.RANDOM_PIC, { ...axiosConfig, responseType: "arraybuffer" });

        return `data:image/jpeg;base64,${Buffer.from(response.data, "binary").toString("base64")}`;
}

Works like a charm now :)

MustSeeMelons
  • 636
  • 1
  • 10
  • 22