通过JS加载图像的S3存储桶CORS错误

时间:2019-02-21 18:48:56

标签: javascript amazon-s3 cors html2canvas

我有一个带有公共文件的s3存储桶设置。这是该存储桶的CORS配置-

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/938934/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>HEAD</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>Authorization</AllowedHeader>
</CORSRule>
</CORSConfiguration>

在我的html网页中,我试图从此存储桶访问图像文件,并且能够通过s3存储桶在网页上呈现图像-

<img src="bucketurl/abcd"/>

但是,当我尝试通过javascript加载该图像时,它没有加载并显示cors错误。 (这是第三方插件代码,无法绕过CORS。http://html2canvas.hertzen.com/)-

var imageLoadHandler = function imageLoadHandler(supportsDataImages) {
    return new Promise(function (resolve, reject) {
        var img = new Image();
        img.onload = function () {
            return resolve(img);
        };
        //ios safari 10.3 taints canvas with data urls unless crossOrigin is set to anonymous
        if (!supportsDataImages || useCORS) {
            img.crossOrigin = 'anonymous';
        }

        img.onerror = reject;
        img.src = src;
        if (img.complete === true) {
            // Inline XML images may fail to parse, throwing an Error later on
            setTimeout(function () {
                resolve(img);
            }, 500);
        }
        if (_this4.options.imageTimeout) {
            var timeout = _this4.options.imageTimeout;
            setTimeout(function () {
                return reject( true ? 'Timed out (' + timeout + 'ms) fetching ' + src.substring(0, 256) : '');
            }, timeout);
        }
    });
};

这是错误-

Access to image at 'https://bucketurl/abcd' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

我不想打开所有来源的资源。我只想从s3bucket打开资源。为此需要如何以及需要进行哪些更改。

1 个答案:

答案 0 :(得分:0)

您当前的CORS配置允许来自所有来源的GETHEADPOST请求。

但是,某些浏览器确实发送了预检请求 1 来验证服务器支持哪些HTTP请求。

预检请求是一个OPTIONS请求,它是通过特定的标头执行的。您当前的配置只有预检请求,且允许Authorization标头
这意味着发出预检请求的浏览器(例如Google Chrome)将在此注释上失败。

您应该将预检请求中发送的所有标头的条目作为允许的标头包含在CORS配置中。 2

我建议将CORSRule仅限于您考虑过的来源。不断调整规则,直到找到适合您的应用程序的限制性策略为止。 3

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/938934/">
<CORSRule>
    <AllowedOrigin>http://localhost:8080</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>HEAD</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>Authorization</AllowedHeader>
    <AllowedHeader>/replace with another preflight header/</AllowedHeader>
</CORSRule>
<CORSRule>
    <AllowedOrigin>http://html2canvas.herzen.com</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>OPTIONS</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>Authorization</AllowedHeader>
    <AllowedHeader>/replace with another preflight header/</AllowedHeader>
</CORSRule>
</CORSConfiguration>

在浏览器的“网络”标签中检查预检请求时,可以查看其响应标题。

您还可以指定一个通配符,以匹配预检请求中的允许所有标头。

    <AllowedHeader>*</AllowedHeader>