钉钉h5应用利用jsapi提供的接口上传图片到ali-oss

这里是利用钉钉jsapi 提供的chooseImage(拍照或者选择本地照片),compressImage(压缩图片),uploadFile(上传本地资源到开发者服务器)接口来完成对图片的上传。

第一步,安装jsapi

npm i dingtalk-jsapi

第二步,鉴权

钉钉提供了很多的api,一部分需要鉴权,不部分是不需要的。例如dd.scan是不需要鉴权的,dd.chooseImage就需要鉴权(虽然官方文档上标注不需要,但实际需要)。

import * as dd from 'dingtalk-jsapi';

function  apiConfig(path: string) {
   // 通过后端获取签名所需参数
   ajax(path).then((res) => {
     if (res.data.success) {
       const { agentId, timeStamp, nonceStr, signature } = res.data.content;
       dd.config({
         agentId,
         corpId: loginUtil.getCorpId(),
         timeStamp,
         nonceStr,
         signature,
         type: 0,
         jsApiList: ['chooseImage'], // 这里要填写需要鉴权的api
       });

       dd.error((err) => {
         alert('dingTalk config error: ' + JSON.stringify(err))
       }); // 该方法必须带上,用来捕获鉴权出现的异常信息,否则不方便排查出现的问题
     }
  });
}

第三步,唤起相机或相册选择图

dd.chooseImage({
   count: 9,
   sourceType: ['camera', 'album'],
   success: (res) => {
       // 返回结果
       const { files, filePaths } = res;
   },
   fail: (error) => {
       if (Number(error.errorCode) === -1 || Number(error.errorCode) === 11) {
          console.log('chooseImage cancel');
       } else if (Number(error.errorCode) === 7) {
          alert('chooseImage no permission info');
       } else {
          alert('chooseImage=>' + JSON.stringify(error));
       }
   },
   complete: () => {}
});

// 结果 数据结构
/*{
  "files": [
    {
      "path": "https://resource/MzNjMmEwN2FjMjg0YTBkYTI4NTdlYmJhNTI3NDhlZWU=.image",
      "size": 327622,
      "fileType": "jpg"
    },
    {
      "path": "https://resource/ZDNmODkzM2RhNWQwMWI4NzEwOGFlY2U0NzJkY2ZmZjY=.image",
      "size": 317501,
      "fileType": "jpg"
    }
  ],
  "filePaths": [
    "https://resource/MzNjMmEwN2FjMjg0YTBkYTI4NTdlYmJhNTI3NDhlZWU=.image",
    "https://resource/ZDNmODkzM2RhNWQwMWI4NzEwOGFlY2U0NzJkY2ZmZjY=.image"
  ]
}*/

第四步,压缩设置(根据实际情况,可以跳过)

dd.compressImage({
   filePaths, // 上一步获取结果的filePaths
   compressLevel: 3, //压缩级别,支持 0 ~ 4 的整数,默认 4。 0:低质量。 1:中等质量。 2:高质量。 3:不压缩。 4:根据网络适应。
   success: (res) => {
      // 压缩结果
      const { filePaths } = res;
   },
   fail: () => {},
   complete: () => {}
});

第五步,上传到阿里云

官方文档指出为了您的数据安全,建议使用签名方式上传文件。所以这里不得下载两个库。

npm i crypto-js js-base64

使用dd.uploadFile上传图片

import { Base64 } from 'js-base64';
import crypto from 'crypto-js';
import * as dd from 'dingtalk-jsapi';

// 计算签名。
function computeSignature(accessKeySecret, canonicalString) {
  return crypto.enc.Base64.stringify(
    crypto.HmacSHA1(canonicalString, accessKeySecret)
  );
}

interface DingTalkFileVo {
  path: string;
  size: number;
  fileType: string;
}

//设置上传路径 我这里是是后端设置的路径加上uuid
function getPathDingTalk(file: DingTalkFileVo, path?) {
   const randomId = uuidv4();
   let key = '';
   if (path) {
      key = path;
   } else {
     key = 'image/';
   }
   return key + randomId + '.' + file.fileType;
}

interface DingTalkUpladFileParam {
  url: string;
  header?: { [key: string | number]: any };
  fileName: string;
  filePath: string;
  fileType: string;
  formData?: { [key: string | number]: any };
}

function uploadFile() {
   getOssToken().then((res) => {
       const host = res.data.content.host;
       const params = {} as DingTalkUpladFileParam;
       params.fileName = 'file';
       params.filePath = file.path;
       params.url = this.host;
       params.fileType = file.fileType;
       const date = new Date();
       date.setHours(date.getHours() + 24);
       const policyText = {
          expiration: date.toISOString(), // 设置policy过期时间。
          conditions: [
              // 限制上传大小。
              ['content-length-range', 0, 50 * 1024 * 1024]
          ]
       };
       const policy = Base64.encode(JSON.stringify(policyText)); // policy必须为base64的string。
       const signature = computeSignature(.data.content.accessKeySecret,policy);
       params.formData = {
           OSSAccessKeyId: res.data.content.accessKeyId,
           'x-oss-security-token': res.data.content.securityToken,
           key: getPathDingTalk(file, res.data.content.path),
           signature,
           policy,
           success_action_status: '200' // 让服务端返回200,不然,默认会返回204
       };
       params.header = {
           'x-oss-object-acl': 'public-read' // 指定Object的访问权限
       };
       dd.uploadFile(params).then((response) => {
           // 上传结果
           const result = host + '/' + response
       });
   });
}

参考官方文档

钉钉客户端SDKicon-default.png?t=N7T8https://open.dingtalk.com/document/orgapp/read-before-development
阿里云对象存储icon-default.png?t=N7T8https://help.aliyun.com/zh/oss/?spm=a2c4g.11186623.0.0.6642b9199qnUMt

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值