难点:其实也不难,只不过没做过

知识点: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上传,我也写了一个文章,欢迎点评!

react/vue中调用Bos(百度@baiducloud/sdk)直接上传

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐