createPresignedPost()
函数不适合我,而且很难确定代码的哪一部分是错误的,因为错误没有显式地声明它。
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
import { createPresignedPost } from "@aws-sdk/s3-presigned-post";
import { env } from "@/env/server.mjs";
// Instantiating the client
const accessKeyId = env.AWS_S3_ACCESS_KEY;
const secretAccessKey = env.AWS_S3_SECRET_KEY;
const client = new S3Client({
region: "us-east-1",
credentials: { accessKeyId, secretAccessKey },
});
// Defining variables
const Bucket = "my-unique-awsbucket";
const Key = "user/" + 123 + "/avatar";
const Fields = {
acl: "public-read",
key: Key,
};
// Getting the presignedPost info
const { url, fields } = await createPresignedPost(client, {
Bucket,
Key,
Fields,
Expires: 600, // Expires in 10 minutes
});
这些是我得到的回报
{
url: "https://s3.us-east-1.amazonaws.com/my-unique-awsbucket",
fields: {
acl: 'public-read',
key: 'user/123/avatar',
bucket: 'my-unique-awsbucket',
'X-Amz-Algorithm': 'AWS4-HMAC-SHA256',
'X-Amz-Credential': '<IAM_user_id>/20221015/us-east-1/s3/aws4_request',
'X-Amz-Date': '20221015T170146Z',
Policy: 'hidden',
'X-Amz-Signature': 'hidden'
}
}
我要发布到s3的代码
import FormData from "form-data";
const form = new FormData();
Object.entries(fields).forEach(([field, value]) => {
form.append(field, value);
});
const imagepath = path.join(process.cwd(), "mountains.jpg");
const img = fs.readFileSync(imagepath); // <- Also tried a readstream but no difference
form.append("file", img);
// As per docs
form.submit(url, (err, res) => {
if (err) {
console.log("form.submit: err", err);
}
console.log("Done.")
});
AWS博士 \
根据我尝试的内容,我得到的错误是不同的。
Access Denied
。MissingContentLength - You must provide the Content-Length HTTP header
...当我添加那个头和文件的大小时,它是AccessControlListNotSupported - The bucket does not allow ACLs
。我在Fields
下删除acl密钥,然后使用MalformedPOSTRequest - The body of your POST request is not well-formed multipart/form-data
错误。form.submit
试一试.它甚至没有显示错误,但在桶中没有显示任何图像。secretAccessKey
时,它仍然会释放出一个url
和field
参数,所以如果IAM是错误的,或者我的发布方法,或者标题,或者文件类型,就很难缩小范围.AWS:我的IAM用户只允许用户使用PutObject
访问级别。我觉得这有足够的权限?我没有看到PostObject
权限,所以我认为Put就足够了,或者我可能授予了错误的权限,因为我是POSTing而不是PUTing?
我的水桶政策
{
"Version": "2012-10-17",
"Id": "Policy123",
"Statement": [
{
"Sid": "hidden",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-unique-awsbucket/*"
}
]
}
我的CORS政策
[
{
"AllowedHeaders": [
"*"
],
"AllowedMethods": [
"PUT",
"POST",
"HEAD",
"GET"
],
"AllowedOrigins": [
"*"
],
"ExposeHeaders": []
}
]
有没有人有一个明确的例子,如何上传到这个预先签名的URL?
发布于 2022-10-15 19:15:02
最后这件事对我有用。值得注意的是:
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
import { createPresignedPost } from "@aws-sdk/s3-presigned-post";
import fs from "fs";
import path from "path";
import FormData from "form-data";
const getPresignedPostUrl = async ({ id }) => {
// Instantiating the client
const client = new S3Client({
region: "us-east-1",
credentials: {
accessKeyId: <enter-access-key-id>,
secretAccessKey: <enter-secret-access-key>,
},
});
const filename = "mountains.jpg";
// Creating the presignedPostUrl
const { url, fields } = await createPresignedPost(client, {
Bucket: "my-unqiue-awsbucket",
Key: `user/${id}/${filename}`,
Conditions: [
{ bucket: "my-unqiue-awsbucket" },
["starts-with", "$key", `user/${id}`],
["content-length-range", 0, 1000000],
],
Fields: {
key: `user/${id}/${filename}`,
},
Expires: 600, // Expires in 10 minutes
});
// Filling in the form data with the `form-data` package
const formData = new FormData();
Object.entries(fields).map(([key, value]) => {
formData.append(key, value);
});
const imgpath = path.join(process.cwd(), filename);
const file = fs.readFileSync(imgpath, "utf-8");
formData.append("file", file);
// POSTing the form to aws
formData.submit(url, (err, res) => {
if (err) {
console.log("form.submit: err", err.response.data);
}
console.log("Done.", res.response);
});
};
修改:在使用浏览器时尝试了这个名为ky-universal
或ky
的库,哇,它只是起作用了,而且代码比axios少得多。下面是与AWS S3相关的S3。
Amendment2:got
包也运行得很好。只需将ky
替换为got,语法相同--非常简单,而且代码少得多。显然,它是由相同的人制作的,ky
用于浏览器,got
用于nodejs/服务器端请求。
import ky from 'ky-universal';
const response = await ky.post(url, {
body: formData
});
https://stackoverflow.com/questions/74081648
复制相似问题