在 s3 预签名 url 获取上出现 CORS 错误

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

我正在尝试对我设置到 s3 存储桶的预签名 URL 进行 put fetch,但它一直给我带来 cors 错误。我的目标是通过 presignedUrl 上传图像。

控制台中的主要错误:

可以从源地址 {my presignedURL} 获取数据 “http://localhost:3000”已被 CORS 策略阻止:响应 预检请求未通过访问控制检查:否 请求中存在“Access-Control-Allow-Origin”标头 资源。如果不透明的响应满足您的需求,请设置请求的 模式设置为“no-cors”以在禁用 CORS 的情况下获取资源。

这是我的抓取功能:

const uploadFileToS3 = async (url, data) => {
  try {
    const response = await fetch(url, {
      method: "PUT",
      headers: {
        "content-type": `image/*`
      },
      body: data,
      mode: 'cors',

    });

    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }

    return await response.text();
  } catch (error) {
    console.error(error);
  }
};


export default uploadFileToS3;

我不知道发生了什么,因为在尝试解决此问题时,我已将 s3 存储桶的 CORS 和策略配置设置为非常开放。

CORS 政策:

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "PUT",
            "GET",
            "POST",
            "DELETE"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": []
    }
]

桶政策:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Statement1",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::caption-this-bucket"
        }
    ]
}

我已经浏览了大约一百次,所以我很确定它们是正确的,但当我发现我在其中犯了一些错误时,我会感到欣慰,因为它们很容易修复。该错误是在预检提取或其他操作期间发生的,即提取选项,这是我模糊理解的。在浏览器开发工具的网络选项卡中,Access-Control-Request-Headers:设置为内容类型,我不知道这是否有什么关系,但chatgpt这么认为。

网络请求头: enter image description here enter image description here

我希望我能说些更有帮助的话,但我真的不知道发生了什么。从我在其他帖子中看到的情况来看,这可能是由很多原因造成的。

如果它有用,这里是创建 presignedUrl 的函数:


const { fromIni } = require("@aws-sdk/credential-providers");
const {HttpRequest} = require('@smithy/protocol-http');
const { S3RequestPresigner, getSignedUrl } = require('@aws-sdk/s3-request-presigner');
const { parseUrl } = require('@smithy/url-parser');
const { formatUrl } = require('@aws-sdk/util-format-url');
const { Hash } = require('@smithy/hash-node');


 async function generatePresignedUrl (key) {
  const createPresignedUrlWithoutClient = async ({ region, bucket, key }) => {
    const url = parseUrl(`https://${bucket}.s3.${region}.amazonaws.com/${key}`);
    const presigner = new S3RequestPresigner({
      credentials: fromIni({
        filepath: "./utils/aws-config.ini",
      }),
      region,
      sha256: Hash.bind(null, "sha256"),
    });
  
    const signedUrlObject = await presigner.presign(
      new HttpRequest({ ...url, method: "PUT" }),
    );

    return formatUrl(signedUrlObject);
  };

  const clientURL = await createPresignedUrlWithoutClient({
    region: 'us-west-1',
    bucket: 'caption-this-url',
    key: key
  });

  return(clientURL);
};

module.exports = generatePresignedUrl;

如果您想查看更多代码并且不想等我回复,这里是它的 git 存储库,这是一个小组项目:https://github.com/Greeny467/caption-this

我几个小时以来一直试图找出这个错误,但没有成功。任何帮助都值得赞赏。我很乐意回答任何问题或提供任何额外的代码。我只是有点兴奋,因为我有一个项目要到期,在这个错误得到解决之前我们无法完成。感谢您的帮助。

我正在使用AWS s3和apollo(apollo是项目要求)。我设置的是服务器端的突变,在其解析器中,使用前面提到的 presignedUrl 生成函数为用户生成 presignedUrl 并返回它。然后,一旦用户获得 url,我就会将其与用户上传的任何图像一起使用,以将 PUT 获取请求发送到存储桶。

我期待它上传图像,但没有骰子。

我尝试过的一些事情: 配置CORS策略 配置桶策略 更改获取中的标头 在我的 server.js 中配置 cors 将 cors 添加为 fetch 的模式

没有任何效果

amazon-s3 cors pre-signed-url preflight
1个回答
0
投票

如果您尝试使用 AWS 开发工具包而不是使用预签名 URL,该怎么办?

const uploadFileToS3 = async (fileBody, bucket, key, region) => {
  const s3 = new AWS.S3({
    apiVersion: '2006-03-01',
    region: region,
  });

  const params = {
    Bucket: bucket,
    Key: key,
    Body: fileBody
  };
  
  try {
    const data = await s3.upload(params)
      .on('httpUploadProgress', progress => {
        let progressPercentage = Math.round(progress.loaded / progress.total * 100);
        console.log(`progress: ${progressPercentage}`);
      })
      .promise();
    console.log('File uploaded to S3:', data.Key);
  } catch (err) {
    console.error('Error uploading file :', err);
  }
};
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.