GCP 签名 URL 的 CORS 问题
Posted
技术标签:
【中文标题】GCP 签名 URL 的 CORS 问题【英文标题】:CORS issue with GCP signed URL 【发布时间】:2021-06-03 16:14:22 【问题描述】:我正在尝试使用签名 URL 从前端通过 fetch 上传到 GCP,但我遇到了持久性 CORS 问题。
要上传的文件应该嵌入到签名网址中,还是发送到请求正文中的签名网址?
这是错误:
Access to fetch at <signedurl> from origin 'http://my.domain.com:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
这是存储桶上的 CORS 配置:
[
"origin": ["http://gcs.wuddit.com:3000"],
"responseHeader": ["Content-Type", "Authorization", "Content-Length", "User-Agent", "x-goog-resumable", "Access-Control-Allow-Origin"],
"method": ["GET", "POST", "PUT", "DELETE"],
"maxAgeSeconds": 3600
]
这是获取调用:
const uploadHandler = async (theFile, signedUrl) =>
try
const response = await fetch(signedUrl,
method: 'POST',
headers:
'Content-Type': theFile.type,
,
body: theFile,
);
const data = await response;
catch (error)
console.error('Upload Error:', error);
;
签名 URL 示例:
// https://storage.googleapis.com/my-bucket-name/my-filename.jpg?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=wuddit-images-service%40wuddit-427.iam.gserviceaccount.com%2F20210305%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20210305T032415Z&X-Goog-Expires=901&X-Goog-SignedHeaders=content-type%3Bhost&X-Goog-Signature=18a2428f051e59fbeba0a8b97a824bdee0c70cffe1f9cce5696e95b9fd81b74974f1c291e5195e874eac29ede5619c9cf07538f21b442fb81e7fc1e764bb5444f5d7acae78e3f2b5876450fccde122f059348efc6d5d8be1bbef7250a1aa2433957d85e65f51c69e8daf020341cbf8044ed2b532205a331acc3728437c9295b25bb6e61ef71a99798bb38a6f05e664678d5e12aed916ab41d2e2f9e7e0974588b797ebef87f2c0949f7071687d1d12f232e871d892f6cd2da397888285783d5372657822275f56a44f9ca14a21fb4e4d6552d380f9e4a597d12663c51aea0a2bdc0f47994f687b59c9d629c1010245cefc975718f3574cd6ae331aa1b89d797d
【问题讨论】:
它必须在正文中发送(POST 请求),理想情况下是字节数组。你只需要允许CORS。如果有帮助,请尝试阅读文档? cloud.google.com/storage/docs/cross-origin 遇到了同样的问题,除了这个 [react proxy] (create-react-app.dev/docs/proxying-api-requests-in-development) @AntoninGAVREL 我在这里发帖之前阅读了文档并做了它所说的一切,所以我的问题一定是别的。我确信这是我的一些愚蠢的人为错误。 您可能想要检查的一件事是响应的 HTTP 状态代码。如果是 4xx 或 5xx 错误,那么您就会知道存在一些非 CORS 原因,而 CORS 错误只是其副作用。您还应该查看<signedurl>
服务器的任何服务器端日志 - 查看当它从浏览器获取 CORS 预检 OPTIONS 请求时那里记录了哪些消息。
@sideshowbarker 谢谢,但我没有收到任何回复,因为我认为它不会发送到服务器。我认为我需要将我的获取请求中的标头与signedURL 中的内容完全匹配,但我不确定。顺便说一句,如果我直接在浏览器中导航到签名的 URL,我会收到错误消息。我将它添加到我的 OP 中,但我认为这可能是因为我在直接查询中使用 URL,而不是在获取 POST 中使用。
【参考方案1】:
我想通了。我的主。在我的节点 Express 后端,在我用来调用 generateV4UploadSignedUrl() function, I had to
setthe 'Access-Control-Allow-Origin' on the
res 的端点上。
所以这个:
app.get('/api/gcloud', async (req, res) =>
try
const url = await generateV4UploadSignedUrl().catch(console.error);
res.json( url );
catch (err)
console.log('err', err);
);
变成了这样:
app.get('/api/gcloud', async (req, res) =>
res.set('Access-Control-Allow-Origin', 'http://gcs.whatever.com:3000'); // magic line. Note this must match the domain on your GCP bucket config.
try
const url = await generateV4UploadSignedUrl().catch(console.error);
res.json( url );
catch (err)
console.log('err', err);
);
我的存储桶 CORS 配置:
[
"origin": "http://gcs.whatever.com:3000",
"responseHeader": ["Content-Type", "Authorization"],
"method": ["GET", "POST", "PUT", "DELETE"],
"maxAgeSeconds": 3600
]
将以上内容保存到文件中,例如'cors.json',然后 cd 进入你保存文件的位置,然后使用这个 gsutil 命令设置存储桶 CORS 配置:
gsutil cors set cors.json gs://your-bucket-name
【讨论】:
以上是关于GCP 签名 URL 的 CORS 问题的主要内容,如果未能解决你的问题,请参考以下文章
为我的项目对象启用 Google 存储签名 URL 上的 CORS
使用预签名 URL 将文件上传到 Amazon S3 时出现 CORS 错误
[AWS-S3] POST 上的预签名 URL 被 CORS 阻止,尽管 CORS 配置启用它
仅从浏览器使用预签名 URL 上传时出现 AWS S3 CORS 错误