1

I have a question about the application of html2canvas in a custom leaflet deployed to AWS s3.

I have created a custom TileLayer in a leaflet and deployed the data to AWS s3 so that it can be retrieved with the following URL as an example.

http://{s}.somedomain.com/{z}/{x}/{y}.png

In this state, we have succeeded in drawing the map data using react-leaflet.

However, when we try to get the map data image using html2canvas, the map data will not be displayed. In this case, the following error message is output to the console.

Access to image at 'http://{s}.somedomain.com/{z}/{x}/{y}.png' from origin 'http://localhost:3000/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

It looks like a CORS error, but the configuration in AWS S3 is as follows.

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "GET".
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": []
    }
]

As you can see, we are allowing requests from all origins. However, I can't figure out why the above error occurs.

If anyone has encountered such a situation, please let me know the solution.

NK24
  • 11
  • 2

1 Answers1

0

First, if you are not at ease with CORS I recommend this answer : XMLHttpRequest cannot load XXX No 'Access-Control-Allow-Origin' header

Based on what you say, your server CORS are widely open and accept any request from anywhere.

The same problem happened to me and I have understood that It was not really a CORS problem but a caching one. Let me explain...

Leaflet add tiles by manually creating image element in JavaScript and then adding it in the DOM. This way CORS problems are not triggered as JavaScript is not doing request itself.

Once tile requests are made there are also cached at some point. And cache also save headers to be able to match future request. If at first your request did not contains header to allow cross origin, when you are triggering html2canvas with allowCors = true, it won't be able to match what is saved in cache and a CORS error will be thrown.

To see if you have the same problem as me, you can try to disable google chrome cache in inspector and set html2canvas options like this

<script>
html2canvas(map, {
    useCORS: true,
    allowTaint: true,
}).then((canvas: any) => {
    var img = document.createElement('img');
    img.src = canvas.toDataURL('image/png');
    console.log(img.src);
});
</script>

If it works well then you can just add the below line to your tile option

<script>
tileLayer.options.crossOrigin = '';
</script>
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
Victor David
  • 157
  • 7