GCP 签名 URL 的 CORS 问题

问题描述

我正在尝试使用签名 URL 从前端通过 fetch 上传到 GCP,但我遇到了持久性 CORS 问题。

上传文件是应该嵌入到signedurl中,还是在请求正文中发送到signedurl?

这是错误

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);
  }
};

签名网址示例:

// 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

解决方法

我想通了。我的君主。在我的节点 Express 后端,在我用来调用 generateV4UploadSignedUrl() function,I had to setthe 'Access-Control-Allow-Origin' on theres` 的端点上。

所以:

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',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