如何使用 S3 预签名 POST url?

How to use an S3 pre-signed POST url?

其实我是第一次使用s3上传文件。我听说过预签名 urls 但显然,我无法设置文件大小限制,所以我发现“预签名 post urls" 但它有点奇怪!!令人惊讶的是我没有找到任何示例。也许这不是我想要的。

我正在从服务器获得预签名 post url:

const { S3 } = require("aws-sdk");

const s3 = new S3({
  accessKeyId: accessKey,
  secretAccessKey: secretKey,
  endpoint: api,
  s3ForcePathStyle: true,
  signatureVersion: "v4",
});

app.post("/get-url", (req, res) => {
  const key = `user/${uuri.v4()}.png`;
  const params = {
    Bucket: "bucketName",
    Fields: {
      Key: key,
      ContentType: "image/png",
    },
  };

  s3.createPresignedPost(params, function (err, data) {
    if (err) {
      console.error("Presigning post data encountered an error", err);
    } else {
      res.json({ url: data.url });
    }
  });
});

奇怪的是,我得到的 url 不像预签名的 url。它只是端点后跟存储桶名称。没有查询参数。没有选择。

你可能猜到了,我不能用这个 url:

await axios.put(url, file, {
  headers: {
    "Content-Type": "image/png",
  },
});

我什至不知道我应该使用 post 还是两个请求。

我都试过了,没有任何反应。也许预签名 post url 不像预签名 url!

至少给我举个例子!我找不到。

您的方向是正确的,但是您需要更改您正在调用的方法。您当前使用的 createPresignedPost() 的 AWS S3 API 文档指出:

Get a pre-signed POST policy to support uploading to S3 directly from an HTML form.

尝试将此方法更改为 getSignedUrl():

Get a pre-signed URL for a given operation name.

const params = { Bucket: 'bucket', Key: 'key' };
s3.getSignedUrl('putObject', params, function (err, url) {
  if (err) {
    console.error("Presigning post data encountered an error", err);
  } else {
    res.json({ url });
  }
});

或同步:

const params = { Bucket: 'bucket', Key: 'key' };
const url = s3.getSignedUrl('putObject', params)
res.json({ url });
  

或者,通过执行 getSignedUrlPromise():

使用承诺

Returns a 'thenable' promise that will be resolved with a pre-signed URL for a given operation name.

const params = { Bucket: 'bucket', Key: 'key' };
s3.getSignedUrlPromise('putObject', params)
  .then(url => {
     res.json({ url });
  }, err => { 
     console.error("Presigning post data encountered an error", err);
  });

另请阅读 API 文档的注释部分,以确保您了解每种方法的局限性。