当前位置:   article > 正文

AWS S3预签名方上传文件_aws生成一个签名,通过这个签名实现文件上传

aws生成一个签名,通过这个签名实现文件上传

前文

网上有很多S3的上传示例,但都没有一个很完整的流程。这里记录一下使用ajva SDKV2实现的步骤

控制台配置

注意配置跨域。添加put请求跨域

上传流程

前端 服务端 S3 获取预签名url 创建预签名url 返回上传url 返回url 通过url上传文件 更新数据 前端 服务端 S3

后端代码

maven导入

<dependency>
  <groupId>software.amazon.awssdk</groupId>
  <artifactId>s3</artifactId>
  <version>2.19.26</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5

service

public class AmazonService {
    private static final Logger log = LoggerFactory.getLogger(AmazonService.class);

    private S3Presigner presigner;

    @PostConstruct
    private void initializeAmazon() {
        AwsCredentialsProvider credentialsProvider = StaticCredentialsProvider.create(AwsBasicCredentials.create("accessKey", "secretKey"));
        presigner = S3Presigner.builder()
                .region(Region.of("region"))
                .credentialsProvider(credentialsProvider)
                .build();
    }
    public String createPresignedUrl(String keyName, Map<String, String> metadata) {
        AwsRequestOverrideConfiguration override = AwsRequestOverrideConfiguration.builder()
                .putRawQueryParameter("x-amz-acl", ObjectCannedACL.PUBLIC_READ.toString())
                .build();
        PutObjectRequest objectRequest = PutObjectRequest.builder()
                .bucket("bucketName")
                .key(keyName)
                .metadata(metadata)
                .overrideConfiguration(override)
                .build();

        PutObjectPresignRequest presignRequest = PutObjectPresignRequest.builder()
                .signatureDuration(Duration.ofMinutes(10))  // The URL expires in 10 minutes.
                .putObjectRequest(objectRequest)
                .build();


        PresignedPutObjectRequest presignedRequest = presigner.presignPutObject(presignRequest);
        String myURL = presignedRequest.url().toString();
        log.info("Presigned URL to upload a file to: [{}]", myURL);
        log.info("HTTP method: [{}]", presignedRequest.httpRequest().method());

        return presignedRequest.url().toExternalForm();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

controller

    @GetMapping("/getUploadUrl")
    public CommonResult<String> getUploadUrl(@RequestParam("keyName") String keyName){
        Map<String, String> metadata = new HashMap<>();
        return CommonResult.success(this.amazonService.createPresignedUrl(keyName,metadata));
    }
  • 1
  • 2
  • 3
  • 4
  • 5

前端代码

<input  type="file" accept="video/*" @change="handleSecondVideoUploadAll" multiple />
  • 1
async handleSecondVideoUploadAll(event) {
      const { files } = event.target;
      const tempFiles = Array.from(files);
      if (tempFiles) {
      //多文件
        Promise.all(tempFiles.map(async file=>{
          const result = await getUploadUrl("test/"+file.name);//获取url
          return this.put(result.data, file,"test/"+file.name);//
        })).then(results => {
          // 在这里执行下一步操作
          //....执行更新数据操作
          console.log("上传成功")
        }).catch(error => {
          // 处理任何一个promise被reject的情况
          console.error('Error:', error);
        });
      }
    },
    async put(url, data,keyName) {
        return  new Promise(async (resolve,reject) => {
          const formData = new FormData();
          const bold = new Blob([data])
          formData.append('video', data);
          const response = await fetch(url, {
            method: 'PUT',
            headers: { "Content-Type": "video/mp4" },
            body: bold // 二进制数据
          });
          if (!response.ok) {
            reject(new Error(`HTTP error! status: ${response.status}`)) ;
          }
          resolve(keyName)
        })
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

遇到的坑

1.文档难找,以下是相关的文档:
官方文档示例
相关博客
2.签名不匹配,检查请求是否为put请求,accessKey与secretKey是否正确
3.上传文件设置为public-read,使用AwsRequestOverrideConfiguration 配置而不是 PutObjectRequest.acl(“public-read”)
4.前端上传时要添加headers不然视频不是打开而是下载

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/707110
推荐阅读
相关标签
  

闽ICP备14008679号