使用 MapBox loadImage 函数时,仅在 Chrome 中出现 AWS S3 CORS 错误
Posted
技术标签:
【中文标题】使用 MapBox loadImage 函数时,仅在 Chrome 中出现 AWS S3 CORS 错误【英文标题】:AWS S3 CORS error only in Chrome, when using MapBox loadImage function 【发布时间】:2021-02-17 15:53:36 【问题描述】:我正在使用 MapBox,我希望将一些图像添加到我的地图中,这些图像位于 AWS S3 存储桶中。
我使用的 MapBox 函数是loadImage。 loadImage 文档声明“外部域必须支持 CORS。”
我的JS代码类似于:
this.map.on('load', () =>
...
this.map.loadImage("https://my-test-bucket.s3-us-west-1.amazonaws.com/long-uuid-here.png", (error, image) =>
if (error)
console.log(error)
throw error;
// The rest doesn't matter
...
当我的地图在 chrome 中加载时,我收到以下错误:
Access to fetch at 'https://my-test-bucket.s3-us-west-1.amazonaws.com/long-uuid-here.png' from origin 'https://localhost:7000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
我的 AWS S3 CORS 配置如下:
[
"AllowedHeaders": [
"*"
],
"AllowedMethods": [
"GET",
"PUT",
"POST",
"DELETE"
],
"AllowedOrigins": [
"*"
],
"ExposeHeaders": []
]
使用curl -H "origin: localhost" -v "https://my-test-bucket.s3-us-west-1.amazonaws.com/long-uuid-here.png"
,我得到以下输出:
* Connected to my-test-bucket.s3-us-west-1.amazonaws.com (<IP HERE>) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/cert.pem
CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server did not agree to a protocol
* Server certificate:
* subject: C=US; ST=Washington; L=Seattle; O=Amazon.com, Inc.; CN=*.s3-us-west-1.amazonaws.com
* start date: Jul 30 00:00:00 2020 GMT
* expire date: Aug 4 12:00:00 2021 GMT
* subjectAltName: host "my-test-bucket.s3-us-west-1.amazonaws.com" matched cert's "*.s3-us-west-1.amazonaws.com"
* issuer: C=US; O=DigiCert Inc; OU=www.digicert.com; CN=DigiCert Baltimore CA-2 G2
* SSL certificate verify ok.
> GET /default.jpg HTTP/1.1
> Host: my-test-bucket.s3-us-west-1.amazonaws.com
> User-Agent: curl/7.64.1
> Accept: */*
> origin: localhost
>
< HTTP/1.1 200 OK
< x-amz-id-2: bLicG+33kfSamR29vMA3BnhmSV27Afooba6yU6hVOPt0mbckO5gefhXN8Ho7hgAEP58s4hKjCf0=
< x-amz-request-id: E760D53EDC5A9804
< Date: Wed, 04 Nov 2020 22:31:38 GMT
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: GET, PUT, POST, DELETE
< Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method
< Last-Modified: Tue, 11 Aug 2020 22:37:31 GMT
< ETag: "39eb0bbf2cc33ba02f53f8585004f820"
< Accept-Ranges: bytes
< Content-Type: image/jpeg
< Content-Length: 16579
< Server: AmazonS3
所以,看起来我已经从 AWS S3 服务器返回了 Access-Control-Allow-Origin: *
标头。
我在 Firefox 中没有收到任何 CORS 错误。
我的 AWS S3 CORS 配置有问题吗?为什么我在 Chrome v86.0.4240.80 (Official Build) (x86_64) 中收到这些 CORS 错误?
注意:我的存储桶实际上并未命名为“my-test-bucket”。我已更改此问题的 URL/存储桶名称。另外,我在本地使用https://localhost
(使用证书设置它,因为我需要使用仅通过 HTTPS 工作的 W3C 地理定位 API),如果重要的话
【问题讨论】:
【参考方案1】:看起来这是 Chrome 的缓存问题。我在这个问题上找到了答案:CORS problems with Amazon S3 on the latest Chomium and Google Canary,来自 @nassan,它建议将 ?cacheblock=true
作为查询参数添加到 GET 请求中。
所以,将我的代码更改为:
this.map.loadImage(`$dealInfo.properties.logo?cacheblock=true`, (error, image) =>
...
)
解决了 Chrome 中出现的 CORS 错误。
看起来是这个问题:https://bugs.chromium.org/p/chromium/issues/detail?id=409090。
我还在我的脚本标签中添加了crossorigin="anonymous"
。
这似乎是一个 Chrome 缓存问题(标题缓存?)也解释了为什么我可以使用 curl
看到预期的标题,但 Chrome 抱怨它们不存在。
【讨论】:
我和 Chrome 的人在一起——他们的缓存行为是完全合法的,实际上是 S3 的错误,因为它没有在非 CORS 请求上返回 Vary 标头。请参阅forums.aws.amazon.com/thread.jspa?threadID=342401 我试图对其进行总结。 这似乎是 AWS S3 对此有过错。但是,他们似乎已经意识到它有一段时间了,而且还没有解决。因此,目前看来解决方法是可行的。以上是关于使用 MapBox loadImage 函数时,仅在 Chrome 中出现 AWS S3 CORS 错误的主要内容,如果未能解决你的问题,请参考以下文章