0

I'm having a bit of a weird problem with my javascript code...

It basically consists of a script that accesses the exif of a photo and then shows it on an HTML page, more specifically the latitude and longitude of it.

The idea is to then use both the latitude and longitude on a Google maps iframe to then show the location that photo was taken...

That's all working but, until now, I've been using a picture that's stored on the cloud to make the testing...

If I try to make it work with the same exact picture stored locally, no EXIF info will appear on the page...

(I've also tried with some of my own pictures that have exif info and it still doesn't work...)

Why does it seem like Exif-js only works with images stored on a server?

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>EXIF</title>
    <style>
        img{
            width: 500px;
            max-height: auto;
        }   
    </style>    
</head>

<body>

    <!-- If I use this it works: -->

    <img src="https://c1.staticflickr.com/5/4867/30883801817_bf122bc498_o.jpg" id="img1" />

    <!-- If I use this it DOESN'T work: -->

    <img src="image3.jpg" id="img1"/> <!-- IT'S THE SAME IMAGE AND IT DOES HAVE EXIF-->

    <iframe id="mapa_google" src="" width="640" height="480"></iframe>


    <h1>Latitude Exif</h1>
    <p id="local_lat"></p>

    <h1>Longitude Exif</h1>
    <p id="local_lon"></p>

    <h1>Latitude Final</h1>
    <p id="local_lat_final"></p>

    <h1>Longitude Final</h1>
    <p id="local_lon_final"></p>

    <script src="exif.js"></script>

    <script>

        var toDecimal = function (number) {


            var d = Math.floor(number[0]);
            var m = Math.floor(number[1]);
            var s = ((number[1]%1)*60);

            var dms= d+(m/60)+(s/3600);

            return dms

        };


        window.onload=getExif;

        function getExif() {
            img1 = document.getElementById("img1");
            EXIF.getData(img1, function() {

            latitude = EXIF.getTag(this, "GPSLatitude");
            longitude = EXIF.getTag(this, "GPSLongitude");  

            local_lat = document.getElementById("local_lat");
            local_lon = document.getElementById("local_lon");

            local_lat.innerHTML = `${latitude}`;
            local_lon.innerHTML = `${longitude}`;


            latitude_final = toDecimal(latitude);
            local_lat_final = document.getElementById("local_lat_final");
            local_lat_final.innerHTML = `${latitude_final}`;

            longitude_final = toDecimal(longitude);
            local_lon_final = document.getElementById("local_lon_final");
            local_lon_final.innerHTML = `${longitude_final}`;   

            document.getElementById("mapa_google").src = "https://www.google.com/maps/embed/v1/place?key=AIzaSyDQSbRMCIv1gDsT2qRsY8HvLyZP11hte_Y&q="+latitude_final+"+"+longitude_final;        

            });

        }

        getExif();


    </script>

</body>
</html>
Rafael Lopes
  • 63
  • 1
  • 8
  • Are you running this from a local web server, or using `file://` urls? It could be an [origin](https://developer.mozilla.org/en-US/docs/Archive/Misc_top_level/Same-origin_policy_for_file:_URIs) problem or something similar. – Daniel Beck Dec 29 '18 at 17:03
  • @DanielBeck I have the local image in the same folder as the .html file. Both locally on my PC – Rafael Lopes Dec 29 '18 at 17:10
  • That's not what I asked. Are you loading this page via a `http://` url, meaning a local webserver running on your PC, or via `file://` urls, meaning no webserver is involved? If you're using `file://` that's probably the reason it's not working; lots of AJAX and related stuff doesn't work or works differently without a webserver. – Daniel Beck Dec 29 '18 at 17:16
  • @DanielBeck I'm using the "file://" option indeed – Rafael Lopes Dec 29 '18 at 17:22
  • Meanwhile I've also found another image online that does have Exif GPS data yet doesn't work in my code... The image being: http://www.myriad-online.com/images/forum/IMG_4692.jpg So... there must be something very wrong happening here... – Rafael Lopes Dec 29 '18 at 17:29

1 Answers1

0

This is a CORS problem.

Exif-js uses an ajax request to retrieve the image. Ajax calls require CORS access. Pages loaded via file:// URIs don't contain the headers that CORS depends on, and the same-origin policy for these files is implementation-dependent but the safest assumption is to treat every file as having its own unique origin -- which means that loading files without a webserver isn't a good enough way to test anything that involves XHR calls.

Similarly, the site you mentioned in comments as also having this problem is denying CORS access:

[Error] Origin null is not allowed by Access-Control-Allow-Origin.

[Error] XMLHttpRequest cannot load https://myriad-online.com/images/forum/IMG_4692.jpg due to access control checks.

as can be seen by watching the developer console (always a good idea when testing js code...) while running this code snippet:

function getExif() {
  img1 = document.getElementById("img1");
  EXIF.getData(img1, function() {
    // won't be reached in this example
    console.log(this);
  });
}

getExif();
<script src="https://cdn.jsdelivr.net/npm/exif-js"></script>
<img src="http://myriad-online.com/images/forum/IMG_4692.jpg" id="img1" />

You won't be able to run exif-js on files that are hosted by sites which explicitly deny CORS access, but for local testing the simplest solution is going to be to spin up a local webserver and test your files via http:// instead of file:// URIs.

Daniel Beck
  • 20,653
  • 5
  • 38
  • 53