引入阿里云生成签名的包(如果是后端生成则不需要)
- npm安装需要的模块
npm install crypto-js --save
npm install js-base64 --save
- 创建Upload.js
- 在Upload.js 引入安装的包
import Base64 from './js-base64.js';
import Crypto from 'crypto-js';
- 设置阿里云的配置项
//阿里云的前缀地址
const fileHost = "https://xxx.oss-xxx.aliyuncs.com"
const env = {
uploadImageUrl: 'ddriver/questionimg/', //文件存放的位置 前面无需加/
AccessKeySecret: 'xxx', // 阿里云账号的密码
OSSAccessKeyId: 'xxx',// 阿里云账号
timeout: 87600 //这个是上传文件时Policy的失效时间
};
- 设置该文件上传的最大时长(env.timeout)和文件限制 (需在该时间节点内上传完)
const getPolicyBase64 = function() {
let date = new Date();
// 当前的时间戳加上配置项的超时时间
date.setHours(date.getHours() + env.timeout);
let srcT = date.toISOString();
const policyText = {
"expiration": srcT, //设置该Policy的失效时间
"conditions": [
["content-length-range", 0, 5 * 1024 * 1024]
// 设置上传文件的大小限制,5mb
]
};
const policyBase64 = Base64.encode(JSON.stringify(policyText));
return policyBase64;
}
- 根据配置生成阿里云签名
const getSignature = function(policyBase64) {
const accesskey = env.AccessKeySecret;
return Crypto.enc.Base64.stringify(Crypto.HmacSHA1(policyBase64, accesskey));
}
- 创建上传文件函数
/**
* @param {Object}
* url: 本地临时文件路径如 wx:file...xxxx.png 注意!在模拟器上上传的图片地址并无
wx:// 要做好处理
* imgStr: 去掉前缀的图片路径 xxxx.png
* imgStr 是去掉前缀的文件路径
* 这里传未处理的文件地址是因为上传时需用到完整路径
* 这里又传了去掉前缀的文件地址是可以灵活的设置保存的文件名
* */
const uploadFile = function(params) {
const aliyunFileKey = params.imgStr
const aliyunServerURL = env.uploadImageUrl;
const accessid = env.OSSAccessKeyId;
// 根据设置的超时时间生成PoLicy
const policyBase64 = getPolicyBase64();
// 再根据base64编码后的Policy生成签名
const signature = getSignature(policyBase64);
//为了避免代码重复性
const fail = () => uni.showToast({
title:'上传失败,请稍后再试',
icon:'none'
})
// 将返回的函数设置为Promise
return new Promise((resolve, reject) => {
wx.uploadFile({
url: fileHost, // 网站的前缀
filePath: params.url, // 要保持的本地文件地址
fileType: 'image', // 如果要传视频则 将其改成video
name: 'file',// 必传项
formData: {
// 上传到服务器的名字
///aliyunServerURL是文件夹名 如果上传到根目录则不传
'key': aliyunServerURL + aliyunFileKey,
// 文件配置项
'policy': policyBase64,
// 阿里云账号
'OSSAccessKeyId': accessid,
// 上面获得的签名
'signature': signature,
//设置文件上传成功的状态码 默认创建成功返回的状态码为 204
'success_action_status': '200',
},
// 成功的回调
success: res => {
console.log('上传成功', res);
if (res.statusCode != 200) {
fail()
reject(res)
} else {
resolve(res)
}
},
// 失败的回调
fail: err => {
fail()
reject(err)
},
})
})
}
- 导出
export {
uploadFile
}
- 在需要用到的地方引入该文件
import {
uploadFile
} from './Upload.js'
10.调用
await new Promise(async (resolve) => {
//因为在小程序内每次只能上传单张 所以循环调上传图片接口
arr.forEach(async (item, index) => {
// 获取的图片临时地址
const url = arr[index].file.path
// RemoveTempStr = function(str) {
// return /wxfile/.test(str) ? str.replace("wxfile://", '') :
// str.replace(/^http:\/\/(tmp|temp|)\/(\S+)/, '$2')}
const imgStr = this.RemoveTempStr(url)
// 这里传未去掉前缀的文件地址
await uploadFile({
url,
imgStr
})
.then(res => {
index === arr.length - 1 ? resolve( '全部上传完成') : null;
}).catch(err => {
console.log('错误', err);
IsErr = true
return
})
// 判断是否循环完毕
})
if (IsErr) {
await this.ShowModal('网络异常,请稍后再试')
CancelDisplay()
return
}
})
// someting to do ...