AWS SDK预先指定的URL +分段上传

时间:2015-08-04 03:04:31

标签: javascript amazon-s3 pre-signed-url

有没有办法使用生成的预签名网址通过浏览器进行分段上传?

3 个答案:

答案 0 :(得分:2)

Angular - 多部分 Aws 预签名 URL

示例

https://multipart-aws-presigned.stackblitz.io/

https://stackblitz.com/edit/multipart-aws-presigned?file=src/app/app.component.html

下载后端: https://www.dropbox.com/s/9tm8w3ujaqbo017/serverless-multipart-aws-presigned.tar.gz?dl=0

要使用预签名的 url 将大文件上传到 S3 存储桶中,必须使用分段上传,基本上将文件分成许多部分,允许并行上传。

这里我们将留下后端和前端的基本示例。

后端(无服务打字稿)

const AWSData = {
  accessKeyId: 'Access Key',
  secretAccessKey: 'Secret Access Key'
};

有 3 个端点

端点 1:/start-upload

要求 S3 开始分段上传,答案是与将要上传的每个部分相关联的 UploadId。

export const start: APIGatewayProxyHandler = async (event, _context) => {
  const params = {
    Bucket: event.queryStringParameters.bucket, /* Bucket name */
    Key: event.queryStringParameters.fileName /* File name */
  };

  const s3 = new AWS.S3(AWSData);

  const res = await s3.createMultipartUpload(params).promise()

  return {
    statusCode: 200,
    headers: {
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Credentials': true,
    },
    body: JSON.stringify({
      data: {
        uploadId: res.UploadId
      }
    })
  };
}
端点 2:/get-upload-url

为要上传的文件分割的每个部分创建一个预先签名的 URL。

export const uploadUrl: APIGatewayProxyHandler = async (event, _context) => {
  let params = {
    Bucket: event.queryStringParameters.bucket, /* Bucket name */
    Key: event.queryStringParameters.fileName, /* File name */
    PartNumber: event.queryStringParameters.partNumber, /* Part to create pre-signed url */
    UploadId: event.queryStringParameters.uploadId /* UploadId from Endpoint 1 response */
  };

  const s3 = new AWS.S3(AWSData);

  const res = await s3.getSignedUrl('uploadPart', params)

  return {
    statusCode: 200,
    headers: {
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Credentials': true,
    },
    body: JSON.stringify(res)
  };
}
端点 3:/完成上传

上传文件的所有部分后,需要通知它们已经上传,这将使对象在 S3 中正确组装。

export const completeUpload: APIGatewayProxyHandler = async (event, _context) => {
  // Parse the post body
  const bodyData = JSON.parse(event.body);

  const s3 = new AWS.S3(AWSData);

  const params: any = {
    Bucket: bodyData.bucket, /* Bucket name */
    Key: bodyData.fileName, /* File name */
    MultipartUpload: {
      Parts: bodyData.parts /* Parts uploaded */
    },
    UploadId: bodyData.uploadId /* UploadId from Endpoint 1 response */
  }

  const data = await s3.completeMultipartUpload(params).promise()

  return {
    statusCode: 200,
    headers: {
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Credentials': true,
      // 'Access-Control-Allow-Methods': 'OPTIONS,POST',
      // 'Access-Control-Allow-Headers': 'Content-Type',
    },
    body: JSON.stringify(data)
  };
}

前端(Angular 9)

文件被分成10MB的部分

有了文件,请求分段上传到端点 1

使用 UploadId,您可以将文件分成 10MB 的几个部分,并且从每个部分中您可以使用端点 2 获得预先签名的 url 上传

PUT 是将部分转换为 blob 到端点 2 中获得的预签名网址

当您完成每个部分的上传后,您会向端点 3 发出最后一个请求

在所有这一切的例子中,函数uploadMultipartFile

答案 1 :(得分:1)

来自AWS documentation

  

对于请求签名,分段上传只是一系列常规请求,您启动分段上传,发送一个或多个上传部件的请求,最后完成分段上传。您可以单独签署每个请求,签署分段上传请求没有什么特别之处

所以我认为你应该为分段上传的每个部分生成一个预先签名的URL:(

你的用例是什么?你不能从你的服务器执行一个脚本,并给s3访问这个服务器吗?

答案 2 :(得分:1)

通过使用签名版本4为上载的每个零件创建一个规范请求,我得以在无服务器架构中实现了这一目标。您可以在AWS Multipart Upload Via Presign Url

中找到该文档