一、注意问题

今天在学习如何将图片上传到阿里云的时候,遇到的最大的问题是,使用哪些参数,并且如何获取这些参数

二、解决问题

1、参数问题

1.1、参数解释

以下代码为将图片上传到阿里云的代码,

首先uploadfile中的url就是bucket的地址,name为key,以后根据name来调用文件二进制内容,filePath就是要上传的资源的路径

其次formdata中的参数,key值为oss中的存放文件的路径,如果oss‘没有此路径,那么就创建一个,policy为一段经过UTF-8和base64编码的JSON文本,声明了Post请求必须满足的条件,对于验证的Post请求,HTML表单中必须包含policy和Signature信息。

计算Signature的具体流程为:

  1. 创建一个 UTF-8 编码的 policy。
  2. 将 policy 进行 base64 编码,其值即为 policy 表单域填入的值,将该值作为将要签名的字符串。
  3. 使用 AccessKeySecret 对要签名的字符串进行签名,签名方法与Header中签名的计算方法相同(将要签名的字符串替换为 policy 即可)
wx.uploadFile({
          url: 'XXXX',
          name: 'file',
          filePath: path,
          formData: {
            name: res.tempFilePaths[0],
            key: filekey, //上传到OSS的Object名称。如果名称包含路径,如a/b/c/b.jpg,则OSS会自动创建相应的文件夹。
            policy: policyBase64,
            OSSAccessKeyId: 'XXXX',
            signature: signature,
            success_action_status: 200 //如果不设置success_action_status,文件上传成功后则返回204状态码。
          },
          success: res => {
            console.log("上传成功",res)
          },
          fail: function (err) {
            console.log("上传失败",err)
          },
        });
1.2 参数获取方式

uploadFile里面的url,formData里面的OSSAccessKeyId,在创建阿里云OSS的时候获取,还有formData里面的key注意应该是一个变量,不然的话会覆盖阿里云的文件,变量方式下面会提及。这里主要说一下policy和signature的获取方式

阿里云的开放文档里面说 OSS SDK已经实现签名,用户使用OSS SDK不需要关注签名问题,所以,我们只需要在前端引入sdk便可获取(其实应该是后端获取之后发给我们,这样的话会安全一些,不然会暴露自己的appid)。下面是获取代码

//引入js文件,这些文件基本放在utils中,utils是存放公共组件的地方
var Base64 = require('../../utils/Base64.js');
require('../../utils/hmac.js');
require('../../utils/sha1.js');
var Crypto = require('../../utils/crypto.js');
//使用这些包,编写获取policy和signature的函数
//得到一个base64编码的policy函数
getPolicyBase64:function () {
    var date = new Date();

    date.setHours(date.getHours() + '87600');

    var srcT = date.toISOString();

    var policyText = {
      "expiration": srcT, //设置该Policy的失效时间
      "conditions": [
        ["content-length-range", 0, 5 * 1024 * 1024] // 设置上传文件的大小限制,5mb
      ]
    };

    var policyBase64 = Base64.encode(JSON.stringify(policyText));
    console.log("policyBase64", policyBase64)
    return policyBase64;
  },
//使用AccessKeySecret,policyBase64来进行签名
  getSignature: function (policyBase64) {
    var accesskey = 'XXXXXX';  //此处的accesskey为阿里云的AccessKeySecret
    // console.log(accesskey)

    var bytes = Crypto.HMAC(Crypto.SHA1, policyBase64, accesskey, {
      asBytes: true
    });

    var signature = Crypto.util.bytesToBase64(bytes);
    console.log("signature", signature)
    return signature; //得到最后的签名
  },

三、具体实现的代码

// pages/upimage/upimage.js
const app = getApp()
var Base64 = require('../../utils/Base64.js');
require('../../utils/hmac.js');
require('../../utils/sha1.js');
var Crypto = require('../../utils/crypto.js');
Page({

  /**
   * 页面的初始数据
   */
  data: {

  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
      
  },
    

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  },
  getPolicyBase64:function () {
    var date = new Date();

    date.setHours(date.getHours() + '87600');

    var srcT = date.toISOString();

    var policyText = {
      "expiration": srcT, //设置该Policy的失效时间
      "conditions": [
        ["content-length-range", 0, 5 * 1024 * 1024] // 设置上传文件的大小限制,5mb
      ]
    };

    var policyBase64 = Base64.encode(JSON.stringify(policyText));
    console.log("policyBase64", policyBase64)
    return policyBase64;
  },

  getSignature: function (policyBase64) {
    var accesskey = '57FRzIXvXhbPTAPVzHRSed8NsY5WZS';
    // console.log(accesskey)

    var bytes = Crypto.HMAC(Crypto.SHA1, policyBase64, accesskey, {
      asBytes: true
    });

    var signature = Crypto.util.bytesToBase64(bytes);
    console.log("signature", signature)
    return signature;
  },
  getDateData: function () {
    var myDate = new Date()
    console.log("mydate", myDate)
    var that = this
    myDate.getFullYear(),
      myDate.getMonth(),
      myDate.getDay()
      //得到一个时间戳,用于拼接key
    var selectTime = myDate.getTime() 
    that.setData({
      currentFullYear: myDate.getFullYear(),
      currentMonth: myDate.getMonth() + 1,
      currentDate: myDate.getDate(),
      daselectTime: selectTime
    })
    //将或得到的时间转化成字符串形式并且拼接起来,用于拼接key
    var nowdata = that.data.currentFullYear.toString() + that.data.currentMonth.toString() + that.data.currentDate.toString()
    that.setData({
      danowdate:nowdata
    })
  },
  uploadFile(e) {
   var that=this
   //调用得到一些时间的数据
   that.getDateData()
   //这里我想获取一个0-100的随机数,用于拼接key,追加在时间戳之后,防止命名重复
   var ran= Math.floor(Math.random() * 100)
   var ranstring=ran.toString()
    var policyBase64 = this.getPolicyBase64();
    var signature = this.getSignature(policyBase64);
    wx.chooseImage({
      chooseImage: 1,
      success: res => {
        var path = res.tempFilePaths[0];
        //得到所选文件的后缀名
        console.log(path);
        //获取最后一个.的位置
        var index = path.lastIndexOf(".");
        //获取后缀
        var ext = path.substr(index + 1);
        //拼接key
        var filekey = 'leavephoto' + '/' + that.data.danowdate + '/' + that.data.danowdate + that.data.daselectTime + ranstring + '.' + ext
        console.log("filekey", filekey)
        wx.uploadFile({
          url: 'https://apartment-master.oss-cn-zhangjiakou.aliyuncs.com',
          name: 'file',
          filePath: path,
          formData: {
            name: res.tempFilePaths[0],
            key: filekey, //上传到OSS的Object名称。如果名称包含路径,如a/b/c/b.jpg,则OSS会自动创建相应的文件夹。
            policy: policyBase64,
            OSSAccessKeyId: 'LTAI4Fd5g8ohZaBzPWHQfWXa',
            signature: signature,
            success_action_status: 200 //如果不设置success_action_status,文件上传成功后则返回204状态码。
          },
          success: res => {
            console.log("上传成功",res)
          },
          fail: function (err) {
            console.log("上传失败",err)
          },
        });
      },
    });
    
  },
  
})

四、

代码需要纯函数实现,敬请期待1.0版本

Last modification:December 1st, 2019 at 01:21 pm
如果觉得我的文章对你有用,请随意赞赏