Google Cloud Storage 请求被 CORS 阻止:Access-Control-Allow-Origin 不允许

问题描述 投票:0回答:4

我想实现什么目标?

我正在尝试将文件直接上传到 Google Cloud Storage 存储桶。我通过 Ruby on Rails API ActiveStorage 设置成功创建了一个直接上传链接

使用创建的直接上传链接,我尝试向前端客户端 (Next.js) 中的 Google Cloud Storage 存储桶发出

PUT
请求。

我遇到了什么问题?

在我的前端客户端中,我使用

PUT
发出
fetch
请求并收到以下 CORS 错误

在 Chrome 中:

访问获取 来自源“http://localhost:8080”的“https://storage.googleapis.com//?GoogleAccessId=&Expires=1678985734&Signature=”已被 CORS 策略阻止: 对预检请求的响应未通过访问控制检查:否 请求中存在“Access-Control-Allow-Origin”标头 资源。如果不透明的响应满足您的需求,请设置请求的 模式设置为“no-cors”以在禁用 CORS 的情况下获取资源。

在 Safari 中:

Access-Control-Allow-Origin 不允许 Origin http://localhost:8080。状态代码:200 无法加载资源:Access-Control-Allow-Origin 不允许 Origin http://localhost:8080。状态代码:200

代码详情

根据 Google Cloud 的 CORS 配置,这是我的存储桶的 CORS 策略:

[
  {
    "origin": ["http://localhost:8080"],
    "method": ["GET", "PUT"],
    "responseHeader": ["Origin", "Content-Type", "Content-MD5", "Content-Disposition"],
    "maxAgeSeconds": 3600
  }
]

我已通过运行以下命令确认存在此 CORS 配置:

gcloud storage buckets describe gs://<BUCKET_NAME> --format="default(cors)"

我在前端客户端中的直接上传获取非常简单:

const directUpload = async (directUpload: DirectUpload) => {
  const response = await fetch(directUpload.url, {
    method: 'PUT',
    headers: JSON.parse(directUpload.headers),
    body: file,
  });

  return response;
}

PUT
(来自网络选项卡)的请求标头如下:

Content-Disposition: inline; filename="logo.png"; filename*=UTF-8''logo.png
Content-Type: image/png
Origin: http://localhost:8080
Referer: http://localhost:8080/
Accept: */*
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.6 Safari/605.1.15
Content-MD5: y+5qHSqBo9Kmlkln9P0vAQ==

来自

PUT
请求的 GCS 响应标头(状态代码 403):

alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"
content-length: 363
content-type: application/xml; charset=UTF-8
date: Mon, 20 Mar 2023 16:39:30 GMT
server: UploadServer
x-guploader-uploadid: <UPLOAD_ID>

预检请求的请求标头

:authority: storage.googleapis.com :method: OPTIONS :path: <DIRECT_UPLOAD_PATH> :scheme: https accept: */* accept-encoding: gzip, deflate, br accept-language: en-US,en;q=0.9 access-control-request-headers: content-disposition,content-md5,content-type access-control-request-method: PUT cache-control: no-cache origin: http://localhost:8080 pragma: no-cache referer: http://localhost:8080/ sec-fetch-dest: empty sec-fetch-mode: cors sec-fetch-site: cross-site user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36
来自 

预检请求的 GCS 的响应标头

access-control-allow-headers: Content-Type,Content-MD5,Content-Disposition access-control-allow-methods: GET,PUT access-control-allow-origin: http://localhost:8080 access-control-max-age: 3600 alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43" cache-control: private, max-age=0 content-length: 0 content-type: text/html; charset=UTF-8 date: Thu, 16 Mar 2023 19:26:23 GMT expires: Thu, 16 Mar 2023 19:26:23 GMT server: UploadServer vary: Origin x-guploader-uploadid: <UPLOAD_ID>
我可以看到 

Origin

 标头 
应与我的存储桶 CORS 策略中的 origin 设置相匹配。 尝试的解决方案

我看过许多其他帖子,其中包含类似的 CORS 错误“Access-Control-Allow-Origin 不允许”。从这些帖子中我已经尝试过:

将我的存储桶的 CORS 策略中的 "origin": ["http://localhost:8080"]

更改为
    "origin": ["*"]
  • 在我的前端代码中使用 
    XMLHttpRequest
    而不是
  • fetch
  • 检查
    排查 CORS 请求问题
    建议
  • 清除浏览器缓存和cookie:
google-cloud-platform cors google-cloud-storage rails-activestorage
4个回答
1
投票

在本文中进行更改后,我能够成功向 Google Cloud Storage 发出

PUT

1
投票
https://finnian.io/blog/uploading-files-to-s3-react-native -Ruby on Rails


最后我能够通过强制 Active Storage 使用 v4 来使其工作
GCS 预签名帖子 URL 的。您可以通过设置来实现这一点
storage.yml 中服务的 cache_control 属性。我不知道
为什么这个设置似乎不适用于 v2,但你就知道了。或许
它会对你有帮助。

这涉及按照此处的活动存储指南将

cache_control: "public, max-age=3600"

添加到
google

中我的

storage.yml
服务:
https://edgeguides.rubyonrails.org/active_storage_overview.html#google-cloud-storage-service
我还将 "Cache-Control" 添加到上传到我的 GCS 存储桶 CORS 策略的 

responseHeader

列表中。

这导致向 GCS 成功发出 
PUT
请求,并将文件上传到我的存储桶。

在 Rails 中添加

cache_control
会强制使用

v4

(而不是

v2
)来生成签名 URL。有关签名 URL 的更多信息,请访问:
https://cloud.google.com/storage/docs/access-control/signed-urls#types

• 使用服务帐户身份验证进行 V4 签名:此签名机制如下所述。

• 使用服务帐户身份验证进行 V2 签名:这是用于创建签名 URL 的旧机制,不建议使用它。

当我在本地主机中开发时尝试从存储中“获取”静态文件时,我到达了这篇文章,我所做的解决方法是更新我的存储桶 CORS 策略,如下所示:

0
投票
https://cloud.google.com/storage/docs/cors-configurations#command-line

首先创建一个包含此内容的文件my_local_setup_for_CORS.json

考虑您正在使用的端口

您计划访问的内容类型
  • 您计划用于请求的方法
  • [ { "origin": ["http://localhost:8080"], "responseHeader": ["Content-Type"], "method": ["GET"], "maxAgeSeconds": 3600 } ]
  • 之后在控制台中使用以下命令:
gsutil cors set my_local_setup_for_CORS.json gs://{name-of-your-bucket}

再次尝试时请记住强制重新加载“ctrl+f5”。

    

我通过安装 cors 节点模块并将其添加到请求的服务器上解决了该问题


-5
投票

© www.soinside.com 2019 - 2024. All rights reserved.