ericnograles / browser-image-resizer

A tiny browser-based library to downscale and/or resize images using canvas
MIT License
98 stars 42 forks source link

'TypeError: base64.match(...) is null' when img.src starts with 'data:image/jpeg;charset=utf-8;base64,' #10

Closed tyler-johnson closed 4 years ago

tyler-johnson commented 5 years ago

So it seems like sometimes (still can't figure out when exactly) the browser will report the type of a file with the charset, such as image/jpeg; charset=utf-8. This is apparently valid and used by the Content-Type header.

So I think this library just needs to account for that extra charset part when receiving an image.

tyler-johnson commented 5 years ago

Oh I should add that I am passing readAndCompressImage() a regular File object that happens to have the type marked as image/jpeg; charset=utf-8. The whole data: url part comes from this library.

ericnograles commented 5 years ago

@tyler-johnson Ah, I def must've missed that. I'll check it out tomorrow and see what we can do. Thanks for reporting the issue!

ericnograles commented 5 years ago

@tyler-johnson I'm having trouble replicating this scenario, but I did some research. This might be an issue from the system from which you're sourcing your image.

Here's an old bug from Apache Tomcat back in the day: https://bz.apache.org/bugzilla/show_bug.cgi?id=24970

And here's a bug from another library, FakeXMLHttpRequest: https://github.com/pretenderjs/FakeXMLHttpRequest/issues/14

The TL;DR is that images shouldn't typically have a charset associated with them since they're binary. Charsets seem to make most sense when transmitting text, however, since the consumer will need to know what charset to use to parse the text (ASCII, UTF-8, etc)

In the cases I researched, it seemed like the source system transmitting the images with the charset was doing so incorrectly.

If you can replicate this somehow through a source system you're using that's publicly accessible, I'd be happy to take a look at it either way.

tyler-johnson commented 5 years ago

So I am unfortunately away from the computer that had this originally popped up in. However, I do know that the data for the image was sourced from fetch(), using the .blob() method and then converted to a file using new File([blob], name, { type: blob.type }). Now how the image was served up is a bit convoluted (I'll just say that Webpack was involved) but if I am not mistaken, it was served over HTTP normally, except that the Content-Type header was set with the charset. I'm not a 100% on this, but I will confirm tomorrow. So maybe it's as simple as the fetch API including the charset in the blob?

Also I will say that I have gotten around this by just parsing out the mimetype from blob.type before creating the File, so this isn't really an issue for me anymore.