Search code examples
javascriptimagecanvasbinary-dataexif

Read EXIF data from img in JavaScript (cross-domain friendly)


I recently started building a bookmarklet that displays the EXIF data of any image on a website. I chose to use Nihilogic's binary.js and exif.js libraries. For images hosted on the same domain as the parent page, the script works wonderfully. But because it uses XHR to read the binary data of images, and because XHR is restricted to same-origin requests, I can't access the binary data of any cross-site-hosted images.

Is there a way to load the binary data of an image locally (or at least without using XHR) that preserves EXIF data?

I've explored a few other directions, but I fear I don't understand them well enough to determine if there's a solution:

  • JSONP - I'm assuming there's no way to get binary data into one of these things.
  • canvas tags - these seem to produce very different base64 encodings than what PHP does, and I suspect that the EXIF data no longer exists in the new encoding.

Solution

  • Javascript is allowed to do special operations (like on the canvas) with same-origin images and cors-enabled images because the browser can safely assume that those would be OK to upload to the server in the first place. But then it gets complicated...

    I can't access the binary data of any cross-site-hosted images.

    Yes, generally it is very important that you can't. More to the point, you can't do what you want with a bookmarklet.

    You can't do this with a canvas because the cors rules here are strict (for good reasons!)

    In short the reasoning in general is pretty much exactly the same. Browsers are in a unique security position: A random page on the internet can show you things that are private to you, such as the hypothetical image, C:\MyPhotos\privateImage1.jpg, assuming it could guess that file path.

    But that webpage is most certainly not allowed to do anything with that file other than show it to you. It can't read the binary information (EXIF information or pixel information). JavaScript is not allowed to know what that image looks like or nearly any data associated with it.

    If it was able to figure that out, a random webpage would be able to try a bunch of file paths and maybe come across an image on your hard drive, and then upload the binary data of that image to a server, in effect stealing your private image.


    A browser extension would be far more suited to this task than a (JavaScript) bookmarklet because of this.