微信小程序上传图片到阿里云oss(纯前端)

之前一篇主要写关于vue上传到阿里云服务oss上面,文章地址:vue上传图片到阿里云oss

根据业务需要还需要做小程序端上传,故而也记录一下


文章目录

  • 1. 准备工作
    • 1.2 小程序后台配置阿里云地址
      • 1.2.1 添加合法域名
      • 2. 主要方法
      • 3. 使用步骤
        • 3.1 文件改造
        • 3.2 文件调用
        • 3.3 拓展--canvas签名实现

          1. 准备工作

          1.2 小程序后台配置阿里云地址

          1.2.1 添加合法域名

          小程序后台地址:后台管理地址

          步骤:登录小程序后台 → 开发 → 开发管理 → 开发设置 → 服务器域名 → 修改

          提示:若使用过程中没有报域名问题第一步,或者调试阶段可忽略,只需要在开发者工具中→ 本地设置→ 勾选不校验合法域名即可


          2. 主要方法

          上传方法封装:主要也是使用这位大佬:wxapp-ali-oss-use 封装的方法,方法源码感兴趣可以研究下,我主要记录如何使用

          官方方法地址:微信小程序上传

          3. 使用步骤

          3.1 文件改造

          可以使用npm方式,由于项目不大,直接复制文件到本地目录来进行调取使用

          对alioss.js文件进行个性化改造

          代码示例:

          方法的重点主要是在于policy以及Signature值的获取,其他值都可以固定或者自己控制,只有这两个值是需要算法计算出来的

          const Base64 = require('./alioss/base64.js');
          const Crypto = require('./alioss/crypto.js');
          const aliOSS = { accessKeyID: 'aaaaaaaaaaa',
            accessKeySecret: 'bbbbbbbbbbbb',
            host: 'https://ccccccccccc.oss-cn-hangzhou.aliyuncs.com',
            timeout: 87600,
          };
          export function uploadFile(filePath) { return new Promise(function (resolve, reject) { if (!filePath) { reject({ status: false,
                  err:'文件错误',
                });
                return;
              }
              const aliyunFileKey = 'cecbImages/' + Date.now() + '-' + Math.floor(Math.random() * 1000) + '.png';
              const policyBase64 = Base64.encode(JSON.stringify({ "expiration": new Date(new Date().getTime() + aliOSS.timeout).toISOString(),
                "conditions": [
                  ["content-length-range", 0, 1024 * 1024 * 10]//10m
                ]
              }));
              let bytes = Crypto.util.HMAC(Crypto.util.SHA1, policyBase64, aliOSS.accessKeySecret, { asBytes: true });
              const signature = Crypto.util.bytesToBase64(bytes);
              wx.uploadFile({ url: aliOSS.host,
                filePath: filePath,
                name: 'file',
                formData: { 'key': aliyunFileKey,
                  'OSSAccessKeyId': aliOSS.accessKeyID,
                  'policy': policyBase64,
                  'Signature': signature,
                  'success_action_status': '200',
                },
                success: function (res) { resolve({ url:aliOSS.host+'/' + aliyunFileKey
                  });
                },
                fail: function (err) { console.log(err);
                },
              })
            });
          }
          
          • accessKeyID与accessKeySecret若纯前端实现的话 就是固定写死的,这个在申请阿里云的时候就会给
          • host 是一个拼接路径 bucket名称+ region地区节点(比如 oss-cn-hangzhou)
          • timeout 超时时间
          • aliyunFileKey 这里是上传的key的参数值,也是存放在oss上面的路径+名称(这里使用了随机数,也可以使用时间戳,只要确保唯一性就可以)

            【注意】 上传后的文件地址:aliOSS.host+‘/’ + aliyunFileKey,该地址也是图片的实际获取地址,需要传给后端保存,以便于后期回显使用

            使用Promise将上传成功之后的地址进行返回

            3.2 文件调用

            项目需要,我使用的图片是通过canvas绘制的,但是调用上是一样的,只需要腾讯对图片的暂存路径传进去即可

            import {uploadFile} from './alioss.js'
            ...
            uploadImage(){const that = this
                wx.canvasToTempFilePath({ canvas: this.data.canvas, // canvas 实例
                  success(res) { // canvas 生成图片成功
                    uploadFile(res.tempFilePath).then(res=>{ console.log(res.url)//图片路径
                    })
                  }
                })
            }
            

            3.3 拓展–canvas签名实现

            .wxml文件:

                 

            .scss文件

             // 签字部分
                .signature-canvas { .canvas{ width: 670rpx;
                    height: 260rpx;
                    background-color: #33374A;
                  }
                }
            

            .js文件

             data: { canvas: {},
              },
                onShow() { const query = wx.createSelectorQuery()
                query.select('#myCanvas')
                  .fields({ node: true,
                    size: true
                  })
                  .exec((res) => { const canvas = res[0].node
                    const ctx = canvas.getContext('2d')
                    const dpr = wx.getSystemInfoSync().pixelRatio
                    canvas.width = res[0].width * dpr
                    canvas.height = res[0].height * dpr
                    this.width = canvas.width;
                    this.height = canvas.height;
                    ctx.scale(dpr, dpr)
                    this.ctx = ctx;
                    this.setData({ canvas: canvas
                    })
                  })
              },
              scaleStart(e) { let { x,
                  y
                } = e.touches[0]
                this.ctx.beginPath()
                this.ctx.moveTo(x, y)
                this.ctx.strokeStyle = "#24A6A4";
                this.ctx.lineWidth = '5'
              },
              scaleMove(e) { let { x,
                  y
                } = e.touches[0]
                this.ctx.lineTo(x, y)
                this.ctx.stroke();
                this.ctx.lineCap = "round";
                this.ctx.moveTo(x, y)
              },
              scaleEnd(e) { this.ctx.lineCap = "round";
              },
              clearCanvas() { this.ctx.clearRect(0, 0, this.width, this.height)
                this.setData({ scoreList:[
                    { index:0,
                      title:'专业水平:',
                      value:1
                    },
                    { index:1,
                      title:'服务态度:',
                      value:1
                    },
                    { index:2,
                      title:'解决速度:',
                      value:1
                    },
                  ]
                });
              },
            

            修改线色通过:this.ctx.strokeStyle = “#24A6A4”;

            修改背景色直接在scss里面修改 .canvas{ background-color: #33374A;}