如何正确设置 CORS 以将带有 presignedUrl 的文件上传到 Firebase 存储?
Posted
技术标签:
【中文标题】如何正确设置 CORS 以将带有 presignedUrl 的文件上传到 Firebase 存储?【英文标题】:How can I setup CORS properly to upload file with a presignedUrl to firebase storage? 【发布时间】:2020-09-07 11:55:51 【问题描述】:我一直在尝试将图像直接从我的 react spa 上传到我的 firebase 存储桶,但我无法正确配置 cors。
我使用 GCP 控制台在 muy bucket 中设置 cors 配置,如下:
[
"origin": ["http://localhost:3000"],
"method": ["PUT"],
"responseHeader": [
"Content-Type",
"Access-Control-Allow-Origin",
"x-goog-resumable"],
"maxAgeSeconds": 3600
]
但它在浏览器中不起作用,而是在邮递员中按预期工作。
我的应用实现如下:
首先我在我的节点 api 中生成预签名的 url:
const admin = require('firebase-admin');
const uuid = require('uuid');
admin.initializeApp(
credential: admin.credential.applicationDefault(),
storageBucket: "<BUCKET-NAME>"
);
var bucket = admin.storage().bucket();
const generateSignedUrl = async (userId) =>
const key = `$userId/$uuid.v1().jpeg`;
const options =
version: 'v4',
action: 'write',
expires: Date.now() + 5*60 * 1000,
contentType: 'image/jpeg'
;
const [ url ] = await bucket
.file(key)
.getSignedUrl(options);
return [url, key];
;
然后在 spa 中,我使用 axios 执行 put 请求,以便使用我的节点 api 提供的 presignedUrl 上传文件。
const config =
headers: 'Content-Type': 'application/octet-stream'
;
await axios.put(presignedUrl, file, config);
但是出现了CORS错误:
Access to XMLHttpRequest at 'https://storage.googleapis.com/...' from origin 'http://localhost: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.
【问题讨论】:
简单看一下the docs,你好像配置错了responseHeader
。此外,您需要 REST API 版本,而不是 gsutil
你能通过this troubleshotting steps吗?特别是第 4 点和第 5 点。您的请求中似乎缺少一些听众。
我也看过了,但我没有意识到我的错误是什么,你能具体说明它是什么@llompalles 吗?请
您的错误与Access-Control-Allow-Origin
和Origin
听者有关,这导致CORS 请求失败,如here 所述。远程故障排除很困难,但您能否将 CORS 配置中的 "origin": ["http://localhost:3000"]
更改为通配符 "origin": ["*"]
?
谢谢@llompalles 我解决了这个问题:)
【参考方案1】:
最后我解决了我的问题,我在这里发布了答案,也许它可以帮助其他人。 我有两个问题。
首先,我一直在为所有请求发送一个授权标头,但由于我的 CORS 配置,firebase 没有正确分析它。我决定将预签名上传请求的 auth 标头省略为: delete axios.defaults.headers.common["x-auth-token"];
其次,contentType头设置错误,但由于chrome默认不显示network选项卡中的options请求(out-of-blink-cors),所以总是出现No 'Access-Control-Allow-Origin' header is present..
错误。由于 firefox,我发现了正确的错误后,我将 signedUrl 生成的选项更改为:
const options =
version: 'v4',
action: 'write',
expires: Date.now() + 5*60 * 1000,
contentType: `image/$type`
;
其中 type 是要上传的图片类型,由 spa 提供。
cors 配置按预期工作。
[
"origin": ["http://localhost:3000"],
"method": ["PUT"],
"responseHeader": [
"Content-Type"
],
"maxAgeSeconds": 3600
]
【讨论】:
很好地找到了解决方案!你能accept your own answer吗?它将使其更加明显,并在您找到解决方案时帮助遇到相同问题的人。谢谢!以上是关于如何正确设置 CORS 以将带有 presignedUrl 的文件上传到 Firebase 存储?的主要内容,如果未能解决你的问题,请参考以下文章