普通上传:

1:前端上传到后端(后端服务器带宽限制,极大影响性能)

2:后端保存到文件服务器(同步/异步)

3:后端保存到数据库

签名直传:

1:前端从后端获取签名

2:前端根据签名上传到文件服务器(不走后端)

3:前端返回后端URL保存到数据库

首先保障文件上传服务可以使用

可以搭建一个Minio服务器

docker run -p 9000:9000 --name minio1 \
-e "MINIO_ACCESS_KEY=minio" \
-e "MINIO_SECRET_KEY=minio123" \
-v /mnt/data:/data \
-v /mnt/config:/root/.minio \
minio/minio server /data

使用过程中出现的坑总结(没有问题忽略下面两条)

1:minio上传大文件错误

413:Request Entity Too Large

原因

文件太大超Ingress限制

解决

创建 ingress 时添加 annotations(注释)

metadata:
  annotations:
    nginx.ingress.kubernetes.io/proxy-body-size: 1024m

2:
一般bucket公共读的是不需要添加后缀就可以访问,一般私有的bucket是需要添加的后缀。
出现了奇怪的问题:添加后缀不可以访问,不添加后缀反而可以访问
排查:两处问题:
1: bucket权限错误,设成共有的了(需要私有)
2:获取签名出错
看了看代码objectClient().getSignedURL方法出错

签名直传

首先,前端调用后端接口获取签名

签名直传后端:

    public ResultModel getObsSign(@RequestParam Map<String, String> paramMap) {
        ResultModel resultModel = new ResultModel();
        int defaultTTLSeconds = 60 * 60;
        Long maxLength = 100 * 1024L;
        PostPolicyRequest postPolicyRequest = new PostPolicyRequest(defaultTTLSeconds, maxLength, obsAttributeConfig.getBucket());
        PostPolicyInfo postPolicyInfo = objectClient.generatePostPolicy(postPolicyRequest);
        resultModel.setData(postPolicyInfo);
        return resultModel;
    }

拿到签名信息后,为了确保正确,可以在cmd中进行测试

curl -X POST http://minio.XXXXXX.com/bkqw \
  -H 'content-type: multipart/form-data' \
  -F 'key=2.txt' \
  -F policy=eyJleHBpcmF0aW9uIjoiMjAyMC0wMi0wNVQyMzoxNTo0OC4wMTZaIiwiY29uZGl0aW9ucyI6W1siY29udGVudC1sZW5ndGgtcmFuZ2UiLDAsMTAwMDBdLHsiYnVja2V0IjoiYmtxdyJ9LHsic3VjY2Vzc19hY3Rpb25fc3RhdHVzIjoiMjAwIn0sWyJzdGFydHMtd2l0aCIsIiRrZXkiLCIiXV19 \
  -F AWSAccessKeyId=AKIAICSFADNN8EXAMBLE \
  -F signature=Ezl5w6g1OJMWjDhxN42IPcSk8WA= \
  -F success_action_status=200 \
  -F 'file=@D:\1.txt'

出现下面响应代表签名获得的是没问题的(注意此处对文件大小的限制)

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   986    0     0  100   986      0   962k --:--:-- --:--:-- --:--:--  962k



前端代码开发

util.js

import request from '@/utils/request'
// 获取签名
export function getSign(applicationId) {
  return request({
    url: '/application/' + applicationId + '/sign',
    method: 'get'
  })
}
// 上传
export function uploadBySign(params, host) {
  return request({
    url: host,
    method: 'post',
    headers: { 'Content-Type': 'multipart/form-data' },
    data: params
  })
}

上传图片

    // 前端选中图片
    handleChange(file) {
      this.fileList = []
      this.fileList.push(file)
      this.file = file
      const fileFormat = file.name.substring(file.name.lastIndexOf('.') + 1, file.name.length)
      if (fileFormat.toLowerCase() !== 'jpg' && fileFormat.toLowerCase() !== 'png' && fileFormat.toLowerCase() !== 'jpeg' && fileFormat.toLowerCase() !== 'svg') {
        this.file = ''
        this.$message.error('仅支持.png .jpg .jpeg格式')
        this.$refs['my-upload'].clearFiles()
        this.fileList = []
        return
      }
      var obsData = new FormData()
      obsData.append('key', this.file.name)
      obsData.append('policy', this.sign.encodedPolicy)
      obsData.append('AWSAccessKeyId', this.sign.accessId)
      obsData.append('success_action_status', 200)
      obsData.append('signature', this.sign.postSignature)
      obsData.append('file', this.file.raw, this.file.name)
      uploadBySign(obsData, this.sign.host).then(response => {
        // 省略
      }).catch(() => {
        this.$message.error('保存失败!')
      })
    }

更多前沿技术,面试技巧,内推信息请扫码关注公众号“云计算平台技术”

在这里插入图片描述

Logo

前往低代码交流专区

更多推荐