DigitalOcean 空间预签名链接上传失败 CORS,尽管从仪表板进行了 CORS 配置

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

我已从 Digital Ocean Spaces 仪表板中最大限度地放松了 CORS,如此处的屏幕截图所示 - https://i.stack.imgur.com/8YrRI.png

我按照这里的评论做了这个 - https://www.digitalocean.com/community/questions/can-i-upload-to-spaces-using-a-signed-url?comment=119654

我在后端创建一个签名 URL,如下所示:

import { S3Client as S3ClientConstructor } from '@aws-sdk/client-s3';
import { PutObjectCommand } from '@aws-sdk/client-s3';
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';

const Spaces = new S3ClientConstructor({
  endpoint: 'https://sfo2.digitaloceanspaces.com',
  region: 'sfo2',
  forcePathStyle: false,
  credentials: {
    accessKeyId: process.env.DO_ACCESS_KEY_ID,
    secretAccessKey: process.env.DO_SECRET_ACCESS_KEY
  }
});

const uploadUrl = await getSignedUrl(
    Spaces,
    new PutObjectCommand({
      Bucket: 'my bucket',
      ACL: 'public-read',
      // Folder
      Key: 'dev'
    }),
    {
      // 10min
      expiresIn: 600
    }
  );

然后我从 HTML 前端文件选择器上传,如下所示:

<input
          className="hidden"
          onChange={async function upload(e) {
            setLoading(true);

            if (!e.target.files?.length) {
              // User canceled the file browser.
              return;
            }

            try {
              const uploadUrl = await fetchPresignedUrl();

              const file = e.target.files[0];
              const formData = new FormData();
              formData.append('file', file);

              const res = await fetch(uploadUrl, {
                method: 'PUT',
                body: formData,
                headers: {
                  'Content-Type': file.type,
                  'x-amz-acl': 'public-read'
                }
              });

              console.log('res.status:', res.status);
            } finally {
              setLoading(false);
            }
          }}
          id="upload-button"
          type="file"
        />

但是这仍然给我带来这样的 CORS 错误:

(原因:CORS 标头“Access-Control-Allow-Origin”丢失)。状态代码:403。

编辑后的预签名 URL 为:

https://MY_BUCKET_HERE.sfo2.digitaloceanspaces.com/dev?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=******Faws4_request&X-Amz-Date=20230228T194311Z&X-Amz-Expires=600&X-Amz-Signature=***********&X-Amz-SignedHeaders=host&x-amz-acl=public-read&x-id=PutObject

有人对如何解决这个问题有任何想法吗?

digital-ocean digital-ocean-spaces
2个回答
2
投票

对我来说,使用

const file
而不是使用
FormData()
已经有效。看看我的 CORS 配置:Advanced CORS Options。注意允许的标头。我遇到了和你一样的问题,并在面板上设置
Content-Type
修复了它。


0
投票

对我来说,添加 x-amz-acl 标头解决了问题

await axios.put(
          presignedUrl,
          file,
          {
            headers: {
              "Content-Type": file.type,
              "x-amz-acl": "public-read",
            },
          }
        );
© www.soinside.com 2019 - 2024. All rights reserved.