taro(react/微信小程序)中通过uploadFile调用Bos(PostObject)直接上传
taro(react/微信小程序)中通过uploadFile调用Bos(PostObject)直接上传
·
难点:其实也不难,只不过没做过
知识点:Bos(PostObject)直接上传,这里是官网,点击查看
1.还是先下载依赖
pnpm install -D crypto-js
2.先写解密方法和base64编码方法,再加一个上传数据格式化的事件
import * as CryptoJS from "crypto-js";
const deCodeStr = (str: string, key: string) => {
let dec = CryptoJS.AES.decrypt(
CryptoJS.enc.Base64.stringify(CryptoJS.enc.Hex.parse(str)),
CryptoJS.enc.Utf8.parse(key),
{
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7,
}
);
return CryptoJS.enc.Utf8.stringify(dec);
};
// 我觉得CryptoJS中有base64的方法,但没时间搞清楚怎么用,所以直接cv了一个Base64转换方法,不忙的可以自己研究研究,欢迎评论或者私信我,我也换一下([坏笑])
const newBase64 = {
// Base64字符集
base64Chars:
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
// 编码函数
encode: (str) => {
let result = "";
for (let i = 0; i < str.length; i += 3) {
let a = str.charCodeAt(i);
let b = i + 1 < str.length ? str.charCodeAt(i + 1) : 0;
let c = i + 2 < str.length ? str.charCodeAt(i + 2) : 0;
let a1 = a >> 2,
a2 = ((a & 3) << 4) | (b >> 4),
a3 = ((b & 15) << 2) | (c >> 6),
a4 = c & 63;
result +=
newBase64.base64Chars[a1] +
newBase64.base64Chars[a2] +
(i + 1 < str.length ? newBase64.base64Chars[a3] : "=") +
(i + 2 < str.length ? newBase64.base64Chars[a4] : "=");
}
return result;
},
// 解码函数
decode: (str) => {
let result = "";
let i = 0;
while (i < str.length) {
let a = newBase64.base64Chars.indexOf(str.charAt(i++));
let b = newBase64.base64Chars.indexOf(str.charAt(i++));
let c = newBase64.base64Chars.indexOf(str.charAt(i++));
let d = newBase64.base64Chars.indexOf(str.charAt(i++));
let a1 = (a << 2) | (b >> 4);
let a2 = ((b & 15) << 4) | (c >> 2);
let a3 = ((c & 3) << 6) | d;
result += String.fromCharCode(a1);
if (c != 64) {
result += String.fromCharCode(a2);
}
if (d != 64) {
result += String.fromCharCode(a3);
}
}
return result;
},
};
// 重头戏
const getFileObj = (permits, val) => {
// val为微信小程序所需要上传文件的临时地址(图片和视频都好使)
// 这里需要传入两个参数 permits:上传相关信息加密后的一串码(后端给) psw:解这个码的密码(一般情况下图片和视频密码应该不一样)
let uploadObj = JSON.parse(deCodeStr(permits, psw)); // deCodeStr为上方解密的方法
// 这里一般使用env判断一下环境,没有授权跨域的,开发时需要代理一下,生产环境的地址一般情况下从uploadObj中拿,当然你要乐意写死也行
let endPoint = "上传的https地址";
// 这个name我是为了上传后文件的名字各位可以随便,这里有个地方需要注意,开发者工具和真机的临时地址不一样
// 开发者工具是http://tmp/eJSYBbGIa9mhebf11841dc97c85f25be4618daxxxxxe.jpg
// 真机是wx:/tmp_/eJSYBbGIa9mhebf11841dc97c85f25be4618daxxxxxe.jpg
let name = val.tempFilePath.includes('tmp/')?val.tempFilePath.split('/tmp')[1]:('/' + val.tempFilePath.split('/tmp_')[1]);
// base64 编码
let policy = newBase64.encode(JSON.stringify({
conditions: [{
bucket: uploadObj.bucketName, // Bucket名字
key: uploadObj.objectDir + name // 文件在云上所放的位置
}]
}));
// 整理并且格式化数据
let fileObj = {
url: endPoint,
data: {
accessKey: uploadObj.accessKey, //您的AccessKey
key: uploadObj.objectDir + name, // 文件名
signature: CryptoJS.HmacSHA256(policy, uploadObj.secretKey).toString(CryptoJS.enc.Hex), // signature是根据secret key和policy计算的签名信息,BOS验证signature从而验证Post请求的合法性。
policy: policy, // policy描述表单的限制条件,不包含policy的匿名请求,只能访问公共可读写的bucket。policy必须为base64编码格式
name: 'file', // uploadFile中的name
file: val.tempFilePath // uploadFile中的filePath
}
};
return fileObj
}
3.然后就可以走上传了
const uploadBos = (obj) => {
const uploadTask = Taro.uploadFile({
url: obj.url,
filePath: obj.data[obj.data.name], // 也可以写成 obj.data.file
name: obj.data.name,
formData: {
accessKey: obj.data.accessKey, //您的AccessKey
key: obj.data.key, // 文件名
signature: obj.data.signature,
policy: obj.data.policy,
},
success: (res) => {
// 接口走成功了
if(res.statusCode == 200){
// 上传成功
}else{
// 其他情况
}
},
fail: (err) => {
// 上传失败
console.log(err);
}
});
// 监听上传进度
uploadTask.onProgressUpdate((res) => {
console.log(res);
});
}
// 直接调用 val为临时地址
uploadBos(getFileObj(permits, val))
4.大功告成,微信原生小程序/uni应该差不多,把语法改一下即可,如果是单纯的h5也可以这么写,没啥区别,只需要将Taro.uploadFile改为框架对应的表单上传即可,还有一种更简单的,就是使用sdk上传,我也写了一个文章,欢迎点评!
更多推荐
已为社区贡献2条内容
所有评论(0)