本文主要记录小程序在本地生成七牛云的token,并上传到七牛云的探索历程。
生成token 的 Bucket是七牛云的命名空间, 如图所示: bucket是 hhimg
<button bindtap="chooseImage">选择图片button>
<view>本地文件路径:{{imageLocalPath}}view>
<button bindtap="startUpload">开始上传button>
<image wx:if="{{showImageSrc}}" src="{{showImageSrc}}" mode="widthFix">image>
const utils = require("../../utils/util");
const qiniuUploader = require("../../utils/qiniuUploader");
Page({
/**
* 页面的初始数据
*/
data: {
imageLocalPath: "",
token: "",
showImageSrc: ""
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
let param = {
ak: "eG6z0ExxxxxxsscyH0gCkv_1vSALnyZ20K",
sk: "9YAkRiOz-xxxxxxxnHXhOXmOkbOiqzGtDTu",
bkt: "hhimg"
};
let token = utils.getQiniuToken(param);
utils.initQiniu(token);
this.setData({
token
});
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
},
chooseImage() {
const that = this;
wx.chooseImage({
count: 1,
sizeType: ['original', 'compressed'], // original 原图 compressed 压缩图
sourceType: ['album', 'camera'],
success(res) {
console.log(res);
that.setData({
imageLocalPath: res.tempFilePaths
});
},
complete: (res) => { },
})
},
startUpload() {
let that = this;
var filePath = this.data.imageLocalPath[0];
// var filePath = res.tempFilePaths[0];
// wx.chooseImage 目前微信官方尚未开放获取原图片名功能(2020.4.22)
// 向七牛云上传
qiniuUploader.upload(filePath, (res) => {
that.setData({
'imageObject': res
});
console.log('提示: wx.chooseImage 目前微信官方尚未开放获取原图片名功能(2020.4.22)');
console.log('file url is: ' + res.fileURL);
that.setData({
showImageSrc: res.imageURL
});
}, (error) => {
console.error('error: ' + JSON.stringify(error));
},
// 此项为qiniuUploader.upload的第四个参数options。若想在单个方法中变更七牛云相关配置,可以使用上述参数。如果不需要在单个方法中变更七牛云相关配置,则可使用 null 作为参数占位符。推荐填写initQiniu()中的七牛云相关参数,然后此处使用null做占位符。
// 若想自定义上传key,请把自定义key写入此处options的key值。如果在使用自定义key后,其它七牛云配置参数想维持全局配置,请把此处options除key以外的属性值置空。
// 启用options参数请记得删除null占位符
// {
// region: 'NCN', // 华北区
// uptokenURL: 'https://[yourserver.com]/api/uptoken',
// domain: 'http://[yourBucketId].bkt.clouddn.com',
// shouldUseQiniuFileName: false,
// key: 'testKeyNameLSAKDKASJDHKAS',
// uptokenURL: 'myServer.com/api/uptoken'
// },
{
key: utils.getUUid()
},
(progress) => {
that.setData({
'imageProgress': progress
});
console.log('上传进度', progress.progress);
console.log('已经上传的数据长度', progress.totalBytesSent);
console.log('预期需要上传的数据总长度', progress.totalBytesExpectedToSend);
}, cancelTask => that.setData({ cancelTask })
);
}
})
const qiniuUploader = require("./qiniuUploader");
const Buffer = require('./buffer.js');
const CryptoJS = require('./hmac-sha1.js');
const base64 = require('./enc-base64.js');
const formatTime = date => {
const year = date.getFullYear()
const month = date.getMonth() + 1
const day = date.getDate()
const hour = date.getHours()
const minute = date.getMinutes()
const second = date.getSeconds()
return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
}
const formatNumber = n => {
n = n.toString()
return n[1] ? n : '0' + n
}
const base64ToUrlSafe = (v) => {
return v.replace(/\//g, '_').replace(/\+/g, '-');
}
/**
*
* @param {opt.ak 七牛云 ak opt.sk 七牛云 sk opt.bkt七牛云的命名空间}} opt
*/
const getQiniuToken = (opt) => {
var accessKey = opt.ak;
var secretkey = opt.sk;
var bucket = opt.bkt;
var strdata = {
"scope": bucket,//空间域名
"deadline": Date.parse(new Date()) + 360000 //当前时间截
}
wx.setStorageSync('tokentime', strdata.deadline)
var str = JSON.stringify(strdata);
var encoded = Buffer.from(str).toString('base64');
var encodedStr = base64ToUrlSafe(encoded);
//HmacSHA1加密
var sign = CryptoJS.HmacSHA1(encodedStr, secretkey);
var cod = base64.stringify(sign)
var encodedSign = base64ToUrlSafe(cod);
var token = accessKey + ':' + encodedSign + ':' + encodedStr;
console.log('token', token)
return token;
}
/**
* 初始化七牛云相关配置
* @param {}} token 七牛的加密token
*/
const initQiniu = (token) => {
var options = {
// bucket所在区域,这里是华北区。ECN, SCN, NCN, NA, ASG,分别对应七牛云的:华东,华南,华北,北美,新加坡 5 个区域
region: 'ECN',
// 获取uptoken方法三选一即可,执行优先级为:uptoken > uptokenURL > uptokenFunc。三选一,剩下两个置空。推荐使用uptokenURL,详情请见 README.md
// 由其他程序生成七牛云uptoken,然后直接写入uptoken
uptoken: token,
// 从指定 url 通过 HTTP GET 获取 uptoken,返回的格式必须是 json 且包含 uptoken 字段,例如: {"uptoken": "0MLvWPnyy..."}
// uptokenURL: 'https://[yourserver.com]/api/uptoken',
// uptokenFunc 这个属性的值可以是一个用来生成uptoken的函数,详情请见 README.md
// uptokenFunc: function () { },
// bucket 外链域名,下载资源时用到。如果设置,会在 success callback 的 res 参数加上可以直接使用的 fileURL 字段。否则需要自己拼接
domain: 'https://qiniu.sijitianjian.com',
// qiniuShouldUseQiniuFileName 如果是 true,则文件的 key 由 qiniu 服务器分配(全局去重)。如果是 false,则文件的 key 使用微信自动生成的 filename。出于初代sdk用户升级后兼容问题的考虑,默认是 false。
// 微信自动生成的 filename较长,导致fileURL较长。推荐使用{qiniuShouldUseQiniuFileName: true} + "通过fileURL下载文件时,自定义下载名" 的组合方式。
// 自定义上传key 需要两个条件:1. 此处shouldUseQiniuFileName值为false。 2. 通过修改qiniuUploader.upload方法传入的options参数,可以进行自定义key。(请不要直接在sdk中修改options参数,修改方法请见demo的index.js)
// 通过fileURL下载文件时,自定义下载名,请参考:七牛云“对象存储 > 产品手册 > 下载资源 > 下载设置 > 自定义资源下载名”(https://developer.qiniu.com/kodo/manual/1659/download-setting)。本sdk在README.md的"常见问题"板块中,有"通过fileURL下载文件时,自定义下载名"使用样例。
shouldUseQiniuFileName: false
};
// 将七牛云相关配置初始化进本sdk
qiniuUploader.init(options);
}
/**
* 获取唯一字符串
*/
const getUUid = () => {
var s = [];
var hexDigits = "0123456789abcdef";
for (var i = 0; i < 36; i++) {
s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
}
s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
s[8] = s[13] = s[18] = s[23] = "-";
var uuid = s.join("");
return uuid;
}
module.exports = {
formatTime: formatTime,
getUUid,
formatNumber,
base64ToUrlSafe,
getQiniuToken,
initQiniu
}