我通过 Cloudfront 的签名 URL 提供来自 S3 存储桶的静态内容,该 URL 使用 302 从我的 REST API 重定向。我尝试通过我的前端 Web 应用程序检索该内容,但遇到了与 CORS 相关的问题我的资产 GET 请求中缺少
access-control-*
标头。
发出请求时,初始
OPTIONS
请求返回预期的标头:
Status: 200
access-control-allow-credentials: true
access-control-allow-headers: x-client-version
access-control-allow-methods: GET, HEAD
access-control-allow-origin: https://subdomain.version_number.domain.extension
access-control-expose-headers: Access-Control-Allow-Origin
但是,以下
GET
请求缺少任何相同的 Access-Control-Allow-Credentials
、Access-Control-Allow-Headers
等,在 GET
请求中完全缺失,并且控制台显示:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at [signed_url] (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 200.
Curl 可以工作,但浏览器不行
使用
curl
并设置正确的 origin
我可以看到正在设置正确的 Access-Control-*
标题:
curl -H "Origin: https://subdomain.version_number.domain.extension" --verbose "[signed_url]"
回应:
> Host: mybucket.anotherdomain.com
> User-Agent: curl/8.5.0
> Accept: */*
> Origin: https://subdomain.version_number.domain.extension
> Access-Control-Request-Method: GET
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
< HTTP/2 200
< content-length: 0
< date: Fri, 21 Jun 2024 15:22:50 GMT
< access-control-allow-origin: https://subdomain.version_number.domain.extension
< access-control-allow-methods: GET, HEAD
< access-control-expose-headers: Access-Control-Allow-Origin
< access-control-allow-credentials: true
< vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method
< server: AmazonS3
< x-cache: Miss from cloudfront
< via: 1.1 [].cloudfront.net (CloudFront)
< x-amz-cf-pop: []
< x-amz-cf-id: []
我已使用以下内容配置了 Cloudfront 发行版:
Origin and origin groups: my_s3_bucket
Viewer protocol policy: HTTPS only
Allowed HTTP Methods: GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE
Restrict viewer access: Yes -> trusted key group assigned to the bucket
S3 存储桶 CORS 配置设置为:
[
{
"AllowedHeaders": [
"*"
],
"AllowedMethods": [
"GET",
"HEAD"
],
"AllowedOrigins": [
"https://subdomain.version_number.domain.extension"
],
"ExposeHeaders": [
"Access-Control-Allow-Origin"
]
}
]
Cloudfront -> 存储桶访问策略
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity[ID]"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my_s3_bucket/*"
}
]
}
事实证明,浏览器不支持使用
credentials: true
对 get 请求执行 302:
铬: https://issues.chromium.org/issues/40290910
Mozilla 火狐浏览器: https://bugzilla.mozilla.org/show_bug.cgi?id=1346749
根据 Mozilla 文档,不推荐这种使用凭据重定向流量的方法,应该重构:
服务器通过 HTTP 重定向响应 CORS 请求 到与原始请求不同来源的 URL,这不是 CORS 请求期间允许。
例如,如果请求页面 https://service.tld/fetchdata, HTTP 响应为“301 永久移动”、“307 临时 重定向”或“308 永久重定向”,位置为 https://anotherservice.net/getdata,在此情况下CORS请求会失败 方式。
要解决此问题,请更新您的代码以使用报告的新 URL 重定向,从而避免重定向。
参考: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors/CORSExternalRedirectNotAllowed