微信小程序上传文件至阿里云OSS直传(java后端签名+前端直传)

简介: 当前的通用文件上传方式是通过前端上传到服务器,再由服务器转存至对象存储。这种方式在处理小文件时效率尚可,但大文件上传因受限于服务器带宽,速度较慢。例如,一个100MB的文件在5Mbps带宽的阿里云ECS上上传至服务器需160秒。为解决此问题,可以采用后端签名的方式,使微信小程序直接上传文件到阿里云OSS,绕过服务器中转。具体操作包括在JAVA后端引入相关依赖,生成签名,并在微信小程序前端使用这个签名进行文件上传,注意设置正确的请求头和formData参数。这样能提高大文件上传的速度。

问题描述:通用上传方法都是有前端上传至服务器,再由服务器转存至对象存储。这种方法在小文件图片以及音频传输速度较为可以,但针对于大文件上传时,由于收服务器带块影响速度极慢,后使用对象存储分片上传虽然解决了服务器至oss的时间,但前端值服务器的传输过程还是收带宽影响;通常阿里云ECS带宽5M计算的话100MB*8=800Mb/5Mbps=160秒,所以100MB大小的文件如果是满带宽上传到服务器要160秒,所以速度相当慢。

解决方式:使用后端签名小程序直传方式跳过服务器转存。操作方式如下。阿里云OSS文档 如何在微信小程序环境下将文件上传到OSS_对象存储(OSS)-阿里云帮助中心

JAVA后端签名

  • 引入Maven依赖
<dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>3.8.0</version>
  </dependency>

image.gif

  • 接受参数
Name Type Note
dir String

存储的相对路径。需要计算进policy,因此前端发起putObject请求中key参数的相应字段也要保持一致

  • 返回参数(类型 JSONObject)
Name Type Note
accessId String
policy String Base64编码
signature String
  • 签名参考代码
@GetMapping("/getSign")
    @ResponseBody
    protected AjaxResult getSignature(String dir){
        String endpoint =  "";
        String accessId =  "";
        String accessKey = "";
        try {
            OSSClient ossClient = new OSSClient(endpoint,accessId,accessKey);
            long expireTime = 30;
            long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
            Date expiration = new Date(expireEndTime);
            PolicyConditions policyConds = new PolicyConditions();
            policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
            policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);//根据参数dir计算的policy,如果和前端uploadfile中参数key的相应字段不一致的话是会报错的
            String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
            byte[] binaryData = postPolicy.getBytes();
            String encodedPolicy = BinaryUtil.toBase64String(binaryData);
            String postSignature = ossClient.calculatePostSignature(postPolicy);
            ossClient.shutdown();//业务完成一定要调用shutdown
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("accessId",accessId);
            map.put("policy", encodedPolicy);
            map.put("signature", postSignature);
            return  AjaxResult.success(map);
        } catch (Exception e) {
            //Assert.fail(e.getMessage());
        }
        return null;
    }

image.gif

前端部分(微信小程序)

注意:wx.uploadFile中请求头header需要配置一个"Content-Type": “multipart/form-data”,不然可能会出现formData带不上的情况

           formData中的key参数,是由dir和name组成的,需要和policy中的一致,不然会报policy无效的错误

 

uploadTest:function(){
    wx.chooseImage({
      count: 1,
      success: function(res) {
        //选择图片成功回调
        wx.showLoading({
          title: '上传中',
          mask: true
        })
        var tempPath=res.tempFilePaths[0]
        var dir='punchImg/'
        //发起后端请求签名
        wx.request({
          url: '<Your signature server>',
          data:{dir:dir},
          success:function(res){
            var l=tempPath.length
            var newName = Date.parse(new Date()) + tempPath.substring(l-10)
            //发起putObject请求,直传OSS
            wx.uploadFile({
              url: 'Your oss url',
              filePath: tempPath,
              name: 'file',
              header: {
                "Content-Type": "multipart/form-data"
              },
              formData:{
                name: newName,
                key:dir+newName,
                policy: res.data.policy,
                OSSAccessKeyId: res.data.accessId,
                success_action_status: '200', 
                signature: res.data.signature
              },
              success:function(res){
                wx.hideLoading()
                console.log(res)
              }
            })
          }
        })
      },
    })
  }

image.gif


相关实践学习
对象存储OSS快速上手——如何使用ossbrowser
本实验是对象存储OSS入门级实验。通过本实验,用户可学会如何用对象OSS的插件,进行简单的数据存、查、删等操作。
相关文章
|
11月前
|
机器学习/深度学习 人工智能 NoSQL
JAVA接入DeepSeek大模型接口开发---阿里云的百炼模型
随着大模型的越来越盛行,现在很多企业开始接入大模型的接口,今天我从java开发角度来写一个demo的示例,用于接入DeepSeek大模型,国内的大模型有很多的接入渠道,今天主要介绍下阿里云的百炼模型,因为这个模型是免费的,只要注册一个账户,就会免费送百万的token进行学习,今天就从一个简单的可以执行的示例开始进行介绍,希望可以分享给各位正在学习的同学们。
1932 3
JAVA接入DeepSeek大模型接口开发---阿里云的百炼模型
|
11月前
|
Arthas 监控 Java
拥抱 OpenTelemetry:阿里云 Java Agent 演进实践
拥抱 OpenTelemetry:阿里云 Java Agent 演进实践
551 0
|
Arthas 监控 Java
拥抱 OpenTelemetry:阿里云 Java Agent 演进实践
本文介绍了阿里云 Java Agent 4.x 版本在基于 OTel Java Agent 二次开发过程中的实践与思考,并重点从功能、性能、稳定性、兼容性四个方面介绍了所做的工作。同时也介绍了阿里云可观测团队积极参与开源建设取得的丰厚成果。
1309 110
拥抱 OpenTelemetry:阿里云 Java Agent 演进实践
|
算法 Java Linux
java制作海报四:java BufferedImage 转 InputStream 上传至OSS。png 图片合成到模板(另一个图片)上时,透明部分变成了黑色
这篇文章主要介绍了如何将Java中的BufferedImage对象转换为InputStream以上传至OSS,并解决了png图片合成时透明部分变黑的问题。
793 1
|
存储 SQL 分布式计算
Java连接阿里云MaxCompute例
要使用Java连接阿里云MaxCompute数据库,首先需在项目中添加MaxCompute JDBC驱动依赖,推荐通过Maven管理。避免在代码中直接写入AccessKey,应使用环境变量或配置文件安全存储。示例代码展示了如何注册驱动、建立连接及执行SQL查询。建议使用RAM用户提升安全性,并根据需要配置时区和公网访问权限。具体步骤和注意事项请参考阿里云官方文档。
1090 10
|
前端开发 Java 数据安全/隐私保护
🚀Java后端人眼中的前端,和前端人眼中的有不一样吗?5️⃣🚀
列表最大的特点就是 整齐 、整洁、 有序,跟表格类似,但是他可组合自由度会更高。
254 0
🚀Java后端人眼中的前端,和前端人眼中的有不一样吗?5️⃣🚀
|
存储 前端开发 Java
🚀Java后端人眼中的前端,和前端人眼中的有不一样吗?4️⃣🚀
表格的现在还是较为常用的一种标签,但不是用来布局,**常见显示、展示表格式数据。**因为它可以让数据显示的非常的规整,可读性非常好。
299 0
🚀Java后端人眼中的前端,和前端人眼中的有不一样吗?4️⃣🚀
|
前端开发 Java
🚀Java后端人眼中的前端,和前端人眼中的有不一样吗?3️⃣🚀
段落标签可以把 HTML 文档分割为若干段落,在网页中要把文字有条理地显示出来,离不开段落标签,就如同我们平常写文章一样,整个网页也可以分为若干个段落。
270 0
🚀Java后端人眼中的前端,和前端人眼中的有不一样吗?3️⃣🚀
|
存储 前端开发 Java
🚀Java后端人眼中的前端,和前端人眼中的有不一样吗?2️⃣🚀
  HTML 指的是超文本标记语言 (Hyper Text Markup Language)是用来描述网页的一种语言。HTML 不是一种编程语言,而是一种标记语言 (markup language),标记语言是一套标记标签 (markup tag)。网页是由网页元素组成的 , 这些元素是利用html标签描述出来,然后通过浏览器解析,就可以显示给用户了。
216 0
🚀Java后端人眼中的前端,和前端人眼中的有不一样吗?2️⃣🚀
|
Web App开发 XML 移动开发
🚀Java后端人眼中的前端,和前端人眼中的有不一样吗?1️⃣🚀
浏览器是网页显示、运行的平台,常用的浏览器有IE、火狐(Firefox)、谷歌(Chrome)、Safari和Opera等。我们平时称为五大浏览器。
224 0
🚀Java后端人眼中的前端,和前端人眼中的有不一样吗?1️⃣🚀

相关产品

  • 对象存储