图像保存的 con Amazon S3 存储桶未显示在 HTML5 画布上。跨域问题

Posted

技术标签:

【中文标题】图像保存的 con Amazon S3 存储桶未显示在 HTML5 画布上。跨域问题【英文标题】:Image saved con Amazon S3 bucket not showing on HTML5 canvas. Crossorigin issue 【发布时间】:2016-11-16 20:07:16 【问题描述】:

我的 AWS S3 存储桶上保存了一张图片。这是我的 CORS 配置:

<CORSConfiguration>
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>Authorization</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

另外,bucket 有这个策略:


    "Version": "2012-10-17",
    "Id": "Policy1468082822770",
    "Statement": [
        
            "Sid": "Stmt1468082812651",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::criptolibertad/*"
        
    ]

这是图片:https://criptolibertad.s3.amazonaws.com/Django/0_startproject.jpeg,如您所见,它是公开的。我使用一个名为Croppie 的库来尝试将图像加载到画布中。但是画布没有显示我不知道为什么的图像。 js看起来是这样的:

croppie_div.croppie('bind', 
    url: " carta_magicpy.imagen_base.url ",
    points:  [10,10,300,600]
);

url 属性只是 Django 渲染的一个变量。渲染的时候是这样的:

<img style="opacity: 0;" src="https://criptolibertad.s3.amazonaws.com/Django/0_startproject.jpeg" crossorigin="anonymous" class="cr-image">

注意crossorigin 属性。我进入 Croppie 的源代码并删除了该属性。但后来我得到了错误:

来自来源的图像...已被跨来源资源共享政策阻止加载: 请求中不存在“Access-Control-Allow-Origin”标头 资源

我该如何解决这个问题?

【问题讨论】:

行为变化似乎表明存储桶上的 CORS 配置是正确的,crossorigin="anonymous" 也是正确的。这既明智又令人困惑,因为它暗示它应该一直在工作。你用不同的浏览器做过测试吗? 【参考方案1】:

似乎 CORS 标头仍未正确设置。这个related Croppie issue #119 提到您可以通过查看响应标头来检查。

它是pretty easy to inspect the headers with curl,用于存储在您的存储桶中的图像:

curl -I -H "Origin: https://***.com/questions/38365182" -H "Access-Control-Request-Method: GET" https://criptolibertad.s3.amazonaws.com/Django/0_startproject.jpeg
HTTP/1.1 200 OK
x-amz-id-2: 9AaMwS9s2Im+OV6YlzVKrDW8RnbQqFt4Ygc+pRa3XM4iDmnJqlO8DQ7EjvpT4W4GnhGc0IvoQeI=
x-amz-request-id: CD4E7C50B5186192
Date: Fri, 15 Jul 2016 07:54:52 GMT
Last-Modified: Sat, 09 Jul 2016 05:13:33 GMT
ETag: "5733f7cd0187eb3a840bbe83e2c66a9b"
Accept-Ranges: bytes
Content-Type: image/jpeg
Content-Length: 33402
Server: AmazonS3

与在例如 imgur 上正确设置 CORS 标头相反:

curl -I -H "Origin: https://***.com/questions/38365182" -H "Access-Control-Request-Method: GET" http://i.imgur.com/HMf7XWD.jpg
HTTP/1.1 200 OK
Last-Modified: Wed, 06 Jul 2016 15:07:13 GMT
ETag: "7b01be4b9235542038f6d9793cc2c620"
Content-Type: image/jpeg
Fastly-Debug-Digest: f94b623450bb8143aff369600bf855d6332bb44c12070f02b0fc95648eac6ef3
cache-control: public, max-age=31536000
Content-Length: 2457350
Accept-Ranges: bytes
Date: Fri, 15 Jul 2016 07:55:15 GMT
Age: 277937
Connection: keep-alive
X-Served-By: cache-iad2131-IAD, cache-fra1232-FRA
X-Cache: HIT, HIT
X-Cache-Hits: 1, 1
X-Timer: S1468569315.725739,VS0,VE2
Access-Control-Allow-Methods: GET, OPTIONS
Access-Control-Allow-Origin: *
Server: cat factory 1.0

如您所见,主要区别在于 imgur 返回标头 Access-Control-Allow-MethodsAccess-Control-Allow-Origin,而您的 S3 存储桶不返回。

我已遵循official Amazon documentation on the subject 并将modified CORS configuration 应用于我自己的存储桶,与您的配置不同的是the AllowedHeader element,它定义了允许响应的标头。我将存储桶设置为:

<AllowedHeader>*</AllowedHeader>

这是存储在我的存储桶中的图像的结果标题:

curl -I -H "Origin: https://***.com/questions/38365182" -H "Access-Control-Request-Method: GET" https://so38134984.s3.amazonaws.com/rainbow_dash.png
HTTP/1.1 200 OK
x-amz-id-2: ANxPKoL3JDsLDGerTf8gdcyRU7U4Ozg4eMYJ9ADlX/2qcBmx0dsmAbZxv2h/tFfQIXbkAs+x5iA=
x-amz-request-id: 737E30AE2F8634FC
Date: Fri, 15 Jul 2016 07:53:55 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
Access-Control-Max-Age: 3000
Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method
Last-Modified: Mon, 04 Jul 2016 20:09:19 GMT
ETag: "3ad1bb64b913c2eadab216b96034b990"
Accept-Ranges: bytes
Content-Type: image/png
Content-Length: 148647
Server: AmazonS3

我假设我的图像现在可以在您的 Croppie 脚本中正常工作。

【讨论】:

成功了! ... 谢啦。顺便说一句,我确实相信 AWS 文档对 &lt;AllowedHeader&gt; 选项的详细信息不足。 绝对!亚马逊有一个严重的技术支持管理不善案例 参考文档:docs.aws.amazon.com/AmazonS3/latest/dev/cors.html

以上是关于图像保存的 con Amazon S3 存储桶未显示在 HTML5 画布上。跨域问题的主要内容,如果未能解决你的问题,请参考以下文章

将 base64 字符串保存到 Amazon S3

PHP 将远程图像保存到 Amazon S3

图像未从 Amazon S3 存储桶加载

Amazon S3 图像,无法使用 html5 画布保存,出现受污染的画布错误

获取存储在 Amazon S3 上的图像的图像高度和宽度

使用 amazon sdk 和存储桶策略从 ios 应用程序将图像上传到 amazon s3