提问者:小点点

如何正确设置 CORS,以便将带有预签名网址的文件上传到 Firebase 存储?


我一直在尝试直接从我的反应水疗中心将图像上传到我的火碱桶,但我无法正确配置代码。

我使用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.

共1个答案

匿名用户

最后我解决了我的问题,我在这里发布了答案,也许它可以帮助其他人。我有两个问题。

  • 首先,我一直在为所有请求发送授权标头,但由于我的 CORS 配置 firebase 无法正确分析它。我决定省略预签名上传请求的身份验证标头,如下所示:
    delete axios.defaults.headers.common["x-auth-token"];
    < li >其次,contentType标头设置不正确,但由于chrome默认情况下不显示网络选项卡中的选项请求(不闪烁-cors),< code >没有“Access-Control-Allow-Origin”标头..错误总是出现。由于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
}]