Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XMLHttpRequest and S3, CORS error

I host my photos on S3 bucket. I added CORS configuration for S3 bucket:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
 <AllowedOrigin>*</AllowedOrigin>
 <AllowedMethod>GET</AllowedMethod>
 <ExposeHeader>Accept-Ranges</ExposeHeader>
 <ExposeHeader>Content-Range</ExposeHeader>
 <ExposeHeader>Content-Encoding</ExposeHeader>
 <ExposeHeader>Content-Length</ExposeHeader>
 <ExposeHeader>Access-Control-Allow-Origin</ExposeHeader>
 <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

In my html page, I tried to save image, so I am using the library: https://github.com/tsayen/dom-to-image

domtoimage.toBlob(document.getElementById('my-node'))
.then(function (blob) {
    window.saveAs(blob, 'my-node.png');
});

I got the CORS error:

XMLHttpRequest cannot load http://s3/bucket/path/image.png. No 'Access-Control-Allow-Origin' header is present on the requested resource.

Any Suggestion is appreciated.

like image 501
franco phong Avatar asked Apr 11 '17 12:04

franco phong


People also ask

Does S3 support CORS?

You can apply Cross-Origin Resource Sharing (CORS) rules to your bucket using either the Amazon S3 console or AWS Command Line Interface (AWS CLI).

How does S3 CORS work?

Cross-origin resource sharing (CORS) defines a way for client web applications that are loaded in one domain to interact with resources in a different domain. With CORS support, you can build rich client-side web applications with Amazon S3 and selectively allow cross-origin access to your Amazon S3 resources.

How do I enable CORS on AWS?

Enable CORS support on a REST API resource Sign in to the API Gateway console at https://console.aws.amazon.com/apigateway . Choose the API from the APIs list. Choose a resource under Resources. This will enable CORS for all the methods on the resource.


1 Answers

After long debugging, I found the core issue. All S3 CORS configuration were corrected, nothing to do with the S3. The issue came from the browser caching. This annoying caching prevented S3 response Access-Control-Allow-Origin' header in response, and that's why it caused the error.

The solution: (it's a hacky solution but it worked) I added one line of code in method getAndEncode of dom-to-image.js to prevent the browser caching.

function getAndEncode(url) {
        ...
        url += "?"+(new Date()).getTime(); // this line of code made magic.

        return new Promise(function (resolve) {
            ....
            request.open('GET', url, true);
...

Again, this is a hacky way, I am still opening for any better solution.

like image 158
franco phong Avatar answered Oct 02 '22 08:10

franco phong