我正在尝试对我设置到 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这么认为。
我希望我能说些更有帮助的话,但我真的不知道发生了什么。从我在其他帖子中看到的情况来看,这可能是由很多原因造成的。
如果它有用,这里是创建 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 的模式
没有任何效果
如果您尝试使用 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);
}
};