一、注意问题
今天在学习如何将图片上传到阿里云的时候,遇到的最大的问题是,使用哪些参数,并且如何获取这些参数
二、解决问题
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的具体流程为:
- 创建一个 UTF-8 编码的 policy。
- 将 policy 进行 base64 编码,其值即为 policy 表单域填入的值,将该值作为将要签名的字符串。
- 使用 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版本