文档

小程序场景下直接调用

视觉智能开放平台的API接口推荐使用SDK进行调用,因为调用需要使用AccessKey ID和AccessKey Secret,推荐在服务端进行接入,在客户端直接接入有AccessKey ID和AccessKey Secret泄漏风险,请自行评估风险范围。

说明

阿里云视觉智能开放平台各类目视觉AI能力API接入、接口使用或问题咨询等,请通过钉钉群(23109592)加入阿里云视觉智能开放平台咨询群联系我们。

使用小程序直接调用,请参见请求签名

使用签名机制调用,文件参数当前系统推荐使用上海OSS链接,您需要将文件放入到上海OSS中,具体操作,请参见开通OSS服务。具体调用方式,请参见文件在同地域OSS

如果是其他情况(如本地文件或者其他链接),您需要先显式地将文件转换成上海OSS链接,具体操作,请参见文件URL处理。具体调用方式,请参见文件在本地或不在同一地域 OSS

配置环境变量

配置环境变量ALIBABA_CLOUD_ACCESS_KEY_IDALIBABA_CLOUD_ACCESS_KEY_SECRET

重要
  • 阿里云账号AccessKey拥有所有API的访问权限,建议您使用RAM用户进行API访问或日常运维,具体操作,请参见创建RAM用户

  • 请不要将AccessKey ID和AccessKey Secret保存到工程代码里,否则可能导致AccessKey泄露,威胁您账号下所有资源的安全。

  • Linux和macOS系统配置方法

    1. 在IntelliJ IDEA中打开终端Terminal。

    2. 执行以下命令,配置环境变量。

      <access_key_id>需替换为您RAM用户的AccessKey ID,<access_key_secret>替换为您RAM用户的AccessKey Secret。如果后续需要进行更多权限相关的配置,具体操作请参见使用RAM Policy控制访问权限

      export ALIBABA_CLOUD_ACCESS_KEY_ID=<access_key_id> 
      export ALIBABA_CLOUD_ACCESS_KEY_SECRET=<access_key_secret>
  • Windows系统配置方法

    新建环境变量文件,添加环境变量ALIBABA_CLOUD_ACCESS_KEY_IDALIBABA_CLOUD_ACCESS_KEY_SECRET,并写入已准备好的AccessKey ID和AccessKey Secret。然后重启Windows系统。本操作以Windows 10为例进行说明。

    1. 打开文件资源管理器,在此电脑上右键单击属性。

    2. 在右侧导航栏,单击高级系统配置

    3. 系统属性对话框的高级页签下,单击环境变量

    4. 环境变量对话框中,单击新建(W)image.png

    5. 在弹出的新建系统变量对话框中,添加环境变量ALIBABA_CLOUD_ACCESS_KEY_IDALIBABA_CLOUD_ACCESS_KEY_SECRET,并写入已准备好的AccessKey ID和AccessKey Secret。

    6. 重启Windows系统,使配置生效。

文件在同地域OSS

如果您的文件存放在上海OSS中,可以参考请求签名进行调用。本文以银行卡识别(RecognizeBankCard)为例,仅展示关键步骤及关键代码,完整示例可下载MiniprogramDemo。您如果调用其他算法,请参考注释和实际业务修改相应代码。

  1. 安装crypto-js依赖,该库在计算签名时使用。

    npm install crypto-js
  2. 计算签名。

    /**
     * ========================================================================================================================
     * 以下代码仅仅为了调用服务端接口计算签名,其逻辑可参考文档:https://help.aliyun.com/document_detail/144904.html
     * 这里只是为了Web前端演示,所以将代码写在了Web前端
     * 真正上线不建议将ACCESS_KEY_ID和ACCESS_KEY_SECRET写在Web前端上,会有泄漏风险,建议将请求API接口代码写到您的服务端
     * ========================================================================================================================
     */
    
    //随机数字
    function signNRandom() {
      const Rand = Math.random()
      const mineId = Math.round(Rand * 100000000000000)
      return mineId;
    };
    //Timestamp
    function getTimestamp() {
      let date = new Date();
      let YYYY = pad2(date.getUTCFullYear());
      let MM = pad2(date.getUTCMonth() + 1);
      let DD = pad2(date.getUTCDate());
      let HH = pad2(date.getUTCHours());
      let mm = pad2(date.getUTCMinutes());
      let ss = pad2(date.getUTCSeconds());
      return `${YYYY}-${MM}-${DD}T${HH}:${mm}:${ss}Z`;
    }
    function pad2(num) {
      if (num < 10) {
        return '0' + num;
      }
      return '' + num;
    };
    function ksort(params) {
      let keys = Object.keys(params).sort();
      let newParams = {};
      keys.forEach((key) => {
      newParams[key] = params[key];
      });
      return newParams;
    };
    function createHmac(stringToSign, key) {
      const CrypStringToSign = CryptoJS.HmacSHA1(CryptoJS.enc.Utf8.parse(stringToSign), key);
      const base64 = CryptoJS.enc.Base64.stringify(CrypStringToSign);
      return base64;
    };
    function encode(str) {
      var result = encodeURIComponent(str);
      return result.replace(/!/g, '%21')
      .replace(/'/g, '%27')
      .replace(/\(/g, '%28')
      .replace(/\)/g, '%29')
      .replace(/\*/g, '%2A');
    };
    function sha1(stringToSign, key) {
      return createHmac(stringToSign, key);
    };
    function getSignature(signedParams, method, secret) {
      var stringToSign = `${method}&${encode('/')}&${encode(signedParams)}`;
      const key = secret + "&";
      return sha1(stringToSign, key);
    };
    //参数拼接
    function objToParam(param) {
      if (Object.prototype.toString.call(param) !== '[object Object]') {
        return '';
      }
      let queryParam = '';
      for (let key in param) {
        if (param.hasOwnProperty(key)) {
          let value = param[key];
          queryParam += toQueryPair(key, value);
        }
      }
      return queryParam;
    };
    function toQueryPair(key, value) {
      if (typeof value == 'undefined') {
        return `&${key}=`;
      }
      return `&${encodeURIComponent(key)}=${encode(value)}`;
    };
    function generateUrl(request, httpMethod, endpoint, accessKeySecret) {
      //参数中key排序
      const sortParams = ksort(request);
      //拼成参数
      const sortQueryStringTmp = objToParam(sortParams);
      const sortedQueryString = sortQueryStringTmp.substring(1);// 去除第一个多余的&符号
      //构造待签名的字符串
      const Signature = getSignature(sortedQueryString, httpMethod, accessKeySecret)
      //签名最后也要做特殊URL编码
      request["Signature"] = encodeURIComponent(Signature);
    
      //最终生成出合法请求的URL
      const finalUrl = "https://" + endpoint + "/?Signature=" + encodeURIComponent(Signature) + sortQueryStringTmp;
      return finalUrl;
    }
    说明

    计算签名的逻辑详情请参见请求签名

  3. 封装接口。

    import CryptoJS from 'crypto-js';
    
    /**
     * ========================================================================================================================
     * 以RecognizeBankCard为例。
     * 这里只是为了小程序端演示流程,所以将代码写在了小程序端
     * 真正上线不建议将ACCESS_KEY_ID和ACCESS_KEY_SECRET写在小程序端,会有泄漏风险,建议将请求API接口代码写到您的服务端
     * 请求银行卡识别:https://help.aliyun.com/document_detail/151893.html
     * ========================================================================================================================
     */
    
    // 参数说明:
    // miniProgramType:小程序类型,比如:微信小程序传参数:wx,支付宝/钉钉传参数:my,注意不要传字符串;
    // callback:结果的回调
    function callRecognizeBankCard(miniProgramType, callback) {
      /* 
      创建AccessKey ID和AccessKey Secret,请参考https://help.aliyun.com/document_detail/175144.html。
      如果您用的是RAM用户AccessKey,还需要为RAM用户授予权限AliyunVIAPIFullAccess,请参考https://help.aliyun.com/document_detail/145025.html。
      从环境变量读取配置的AccessKey ID和AccessKey Secret。运行示例前必须先配置环境变量。
      */
      const accessKeyId = process.env.ALIBABA_CLOUD_ACCESS_KEY_ID;
      const accessKeySecret = process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET;
      // 这里endpoint为API访问域名,与类目相关,具体类目的API访问域名请参考:https://help.aliyun.com/document_detail/143103.html
      const endpoint = "ocr.cn-shanghai.aliyuncs.com";
      // API Action,能力名称,请参考具体算法文档详情页中的Action参数,这里以银行卡识别为例:https://help.aliyun.com/document_detail/151893.html
      const Action = "RecognizeBankCard";
      // API_HTTP_METHOD推荐使用POST
      const API_HTTP_METHOD = "POST";
      // API_VERSION为API版本,与类目相关,具体类目的API版本请参考:https://help.aliyun.com/document_detail/464194.html
      const API_VERSION = "2019-12-30";
    
      const request_ = {};
      //系统参数
      request_["SignatureMethod"] = "HMAC-SHA1",
      request_["SignatureNonce"] = signNRandom(),
      request_["AccessKeyId"] = accessKeyId,
      request_["SignatureVersion"] = "1.0",
      request_["Timestamp"] = getTimestamp(),
      request_["Format"] = "JSON",
      request_["RegionId"] = "cn-shanghai",
      request_["Version"] = API_VERSION,
      request_["Action"] = Action;
      //业务参数,请参考具体的AI能力的API文档进行修改,需要注意在调用其他能力时,这里的入参要根据API文档的入参名进行修改,如人脸活体检测API文档里面的参数名称是“Tasks.N.ImageURL”形式的,因为是支持同时检测多个Task的情况,所以入参时是从“Tasks.1.ImageURL”开始的。
      //举例 request_["Tasks.1.ImageURL"] = "传入您的url";
      request_["ImageURL"] = "http://viapi-test.oss-cn-shanghai.aliyuncs.com/viapi-3.0domepic/ocr/RecognizeBankCard/yhk3.jpg";
    
      callApiRequest(miniProgramType, request_, API_HTTP_METHOD, endpoint, accessKeySecret, callback);
    }
    //请求数据
    function callApiRequest(miniProgramType, request_, API_HTTP_METHOD, endpoint, accessKeySecret, callback) {
      const url = generateUrl(request_, API_HTTP_METHOD, endpoint, accessKeySecret);
      miniProgramType.request({
        url: url,
        method: 'POST',
        header: {
          "ContentType": "application/json"
        },
        success: (result) => {
          // 获取结果
          return typeof callback == "function" && callback(result.data)
        },
        fail: (error) => {
          // 获取报错信息
          return typeof callback == "function" && callback(error.data)
        }
      })
    }
    
    // 导出方法
    module.exports = {
      callRecognizeBankCard: callRecognizeBankCard
    }
    说明

    本文以银行卡识别(RecognizeBankCard)为例,如果调用其他算法,请参考注释和实际业务修改相应代码。

  4. 调用接口。

    const client = require("../../utils/client.js");
    // index.js
    Page({
      data: {
          cardNumber: '',
          errorMessage: '',
      },
      callApi: function() {
        client.callRecognizeBankCard(wx, function(result) {
          if(result.Code) {
            // 请处理错误
          } else {
            // 获取银行卡号,这里只是示例,请根据文档获取自己想要的出参
            this.setData({'cardNumber': result.Data.CardNumber});
          }
        }.bind(this));
      }
    })
    说明

    本文以银行卡识别(RecognizeBankCard)为例,如果调用其他算法,请参考注释和实际业务修改相应代码。

  5. Request合法域名配置。

    小程序中请求接口需要配置服务器域名。不同的AI类目对应的域名不一样,详情请参见访问域名

    以微信小程序为例,配置Request合法域名,如下图所示。合法域名

    说明

    在微信小程序中,将代码中的<your appid>需要更换为您的appid。

完整的示例可下载MiniprogramDemo

说明
  • 完整工程仅以银行卡识别(RecognizeBankCard)为例,如果调用其他算法,请参考注释进行相应代码修改。

  • utils/client.js文件中,callRecognizeBankCard函数的accessKeyId、accessKeySecret、endpoint、Action、API_VERSION参数及request_["ImageURL"]这一行代表业务参数。

    例如,您想使用通用分割能力,通过通用分割API文档可知该能力属于分割抠图类目(imageseg20191230),能力名称为SegmentCommonImage,您需要将endpoint改为imageseg.cn-shanghai.aliyuncs.com(注意该域名需要加入小程序白名单),Action改为SegmentCommonImage,API_VERSION为2019-12-30不用修改,request_["ImageURL"]参数名为ImageURL不用修改。获取结果的时候,需要获取ImageURL,其含义不是银行卡号,而是分割后的图片地址。

文件在本地或不在同一地域OSS

如果您的文件在本地或不在同一地域OSS,请参见文件URL处理,显式地将文件转换成上海OSS链接,再进行调用。

本文以银行卡识别(RecognizeBankCard)为例,仅展示关键步骤及关键代码,完整的示例可下载MiniprogramDemo。您如果调用其他算法,请参考注释和实际业务修改相应代码。

  1. 安装js-base64依赖,该库在计算OSS签名时使用。

    npm install js-base64
    说明

    此处仅以微信小程序为例,关于支付宝或者钉钉小程序,请参见小程序中 base64 数据解码&编码示例

  2. 调用GetOssStsToken接口获取临时的OSS STS Token。

    /**
     * ========================================================================================================================
     * 获取oss sts token,使用阿里云视觉智能开放平台官方OSS-Bucket作为临时存储,仅为方便用户方便调试接口使用,文件存储有效期为1天。
     * 这里只是为了Web前端演示流程,所以将代码写在了Web前端
     * 真正上线不建议将ACCESS_KEY_ID和ACCESS_KEY_SECRET写在Web前端,会有泄漏风险,建议将请求API接口代码写到您的服务端
     * ossStsToken获取原理:请参考文档https://help.aliyun.com/document_detail/155645.html,方式二中的其他语言
     * ========================================================================================================================
     */
    function getOssStsToken(callback) {
      
      // 这里endpoint为API访问域名,与类目相关,具体类目的API访问域名请参考:https://help.aliyun.com/document_detail/143103.html
      const endpoint = "viapiutils.cn-shanghai.aliyuncs.com";
      // API Action,能力名称,请参考具体算法文档详情页中的Action参数,这里以银行卡识别为例:https://help.aliyun.com/document_detail/151893.html
      const Action = "GetOssStsToken";
      // API_VERSION为API版本,与类目相关,具体类目的API版本请参考:https://help.aliyun.com/document_detail/464194.html
      const API_VERSION = "2020-04-01";
    
      callApi(endpoint, Action, API_VERSION, null, callback);
    }
    
    /**
     * ========================================================================================================================
     * 通过签名方式调用API,支持平台的任意API。
     * 这里只是为了小程序端演示流程,所以将代码写在了小程序端
     * 真正上线不建议将ACCESS_KEY_ID和ACCESS_KEY_SECRET写在小程序端,会有泄漏风险,建议将请求API接口代码写到您的服务端
     * 签名文档:https://help.aliyun.com/document_detail/144904.html
     * ========================================================================================================================
     */
    function callApi(endpoint, action, version, params, callback) {
      // API_HTTP_METHOD推荐使用POST
      const API_HTTP_METHOD = "POST";
    
      const request_ = {};
      //系统参数
      request_["SignatureMethod"] = "HMAC-SHA1",
      request_["SignatureNonce"] = signNRandom(),
      request_["AccessKeyId"] = accessKeyId,
      request_["SignatureVersion"] = "1.0",
      request_["Timestamp"] = getTimestamp(),
      request_["Format"] = "JSON",
      request_["RegionId"] = "cn-shanghai",
      request_["Version"] = version,
      request_["Action"] = action;
      // 业务参数,请参考具体的AI能力的API文档进行修改
      if(params) {
        for(let key in params) {
          request_[key] = params[key];
        }
      }
    
      callApiRequest(miniProgramType, request_, API_HTTP_METHOD, endpoint, accessKeySecret, callback);
    }
    说明

    更多关于本步骤的原理详情,请参见文件URL处理

  3. 使用临时的OSS STS Token将文件上传到阿里云视觉智能开放平台官方OSS Bucket。

    /**
     * ========================================================================================================================
     * 处理文件和URL,将其上传到阿里云视觉智能开放平台官方OSS-Bucket作为临时存储,该方式仅为方便用户方便调试接口使用,文件存储有效期为1天。
     * ========================================================================================================================
     */
    // 使用oss-client-sdk进行文件上传
    function uploadToTempOss(ossStsToken, tempFilePath, fileName, callback) {
      const host = 'https://viapi-customer-temp.oss-cn-shanghai.aliyuncs.com';
      let formDataParams = getFormDataParams(ossStsToken.AccessKeyId,ossStsToken.AccessKeySecret,ossStsToken.SecurityToken);
      const signature = formDataParams.signature;
      const ossAccessKeyId = ossStsToken.AccessKeyId;
      const policy = formDataParams.policy;
      const key = accessKeyId+'/'+getNonce(6)+'/'+fileName;
      const securityToken = formDataParams['x-oss-security-token']; 
      miniProgramType.uploadFile({
        url: host, // 开发者服务器的URL。
        filePath: tempFilePath,
        name: 'file', // 必须填file。
        formData: {
          key,
          policy,
          OSSAccessKeyId: ossAccessKeyId,
          signature,
          'x-oss-security-token': securityToken // 使用STS签名时必传。
        },
        success: (res) => {
          if (res.statusCode === 204 || res.statusCode === '204') {
            let result = 'https://viapi-customer-temp.oss-cn-shanghai.aliyuncs.com/'+key;
            callback && callback(result);
          } else {
            console.log('upload error', res);
          }
        },
        fail: err => {
          console.log(err);
        }
      });
    }
    /**
     * ========================================================================================================================
     * 以下代码仅仅为了调用OSS上传文件计算签名,其逻辑可参考文档:https://help.aliyun.com/document_detail/92883.html#section-mx7-v31-uy7,客户端签名第二步
     * 这里只是为了Web前端演示,所以将代码写在了Web前端
     * 真正上线不建议将ACCESS_KEY_ID和ACCESS_KEY_SECRET写在Web前端上,会有泄漏风险,建议将请求API接口代码写到您的服务端
     * ========================================================================================================================
     */
    // 计算签名
    function computeSignature(accessKeySecret, canonicalString) {
      return CryptoJS.enc.Base64.stringify(CryptoJS.HmacSHA1(canonicalString, accessKeySecret));
    }
    // 随机字符串
    function getNonce(length) {
      var str = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
      var result = '';
      for (var i = length; i > 0; --i)
          result += str[Math.floor(Math.random() * str.length)];
      return result;
    }
    // 计算上传OSS的计算签名
    function getFormDataParams(stsAccessKeyId,stsAccessKeySecret,securityToken) {
      const date = new Date();
      date.setHours(date.getHours() + 1);
      const policyText = {
        expiration: date.toISOString(), // 设置policy过期时间。
        conditions: [
          // 限制上传大小。
          ["content-length-range", 0, 1024 * 1024 * 1024],
        ],
      };
      const policy = Base64.encode(JSON.stringify(policyText)) // policy必须为base64的string。
      const signature = computeSignature(stsAccessKeySecret, policy)
      const formData = {
        OSSAccessKeyId: stsAccessKeyId,
        signature,
        policy,
        'x-oss-security-token': securityToken 
      }
      return formData
    }

    更多详情,请参见OSS微信小程序直传实践步骤3:获取签名中的客户端签名下的客户端获取STS临时账号并生成签名,以及步骤4:使用微信小程序上传

    对于支付宝或者钉钉小程序,代码中第18行的name: 'file',需要改成fileName: 'file', fileType: 'image',,请参见OSS支付宝小程序直传实践步骤2:获取签名中的客户端签名下的客户端获取STS临时账号并生成签名,以及步骤3:使用支付宝小程序上传

  4. 上传完成之后得到OSS URL地址,按照文件在同地域OSS方式进行调用。

    /**
     * ========================================================================================================================
     * 以RecognizeBankCard为例。
     * 这里只是为了小程序端演示流程,所以将代码写在了小程序端
     * 真正上线不建议将ACCESS_KEY_ID和ACCESS_KEY_SECRET写在小程序端,会有泄漏风险,建议将请求API接口代码写到您的服务端
     * 请求银行卡识别:https://help.aliyun.com/document_detail/151893.html
     * ========================================================================================================================
     */
    // 参数说明:
    // imageUrl:图片url
    // callback:结果的回调
    function callRecognizeBankCard(imageUrl, callback) {
      // 这里endpoint为API访问域名,与类目相关,具体类目的API访问域名请参考:https://help.aliyun.com/document_detail/143103.html
      const endpoint = "ocr.cn-shanghai.aliyuncs.com";
      // API Action,能力名称,请参考具体算法文档详情页中的Action参数,这里以银行卡识别为例:https://help.aliyun.com/document_detail/151893.html
      const Action = "RecognizeBankCard";
      // API_HTTP_METHOD推荐使用POST
      const API_HTTP_METHOD = "POST";
      // API_VERSION为API版本,与类目相关,具体类目的API版本请参考:https://help.aliyun.com/document_detail/464194.html
      const API_VERSION = "2019-12-30";
    
      const params = {};
      //业务参数,请参考具体的AI能力的API文档进行修改,需要注意在调用其他能力时,这里的入参要根据API文档的入参名进行修改,如人脸活体检测API文档里面的参数名称是“Tasks.N.ImageURL”形式的,因为是支持同时检测多个Task的情况,所以入参时是从“Tasks.1.ImageURL”开始的。
      //举例 params["Tasks.1.ImageURL"] = imageUrl;
      params["ImageURL"] = imageUrl;
    
      callApi(endpoint, Action, API_VERSION, params, callback);
    }
    说明

    本文以银行卡识别(RecognizeBankCard)为例,如果调用其他算法,请参考注释和实际业务修改相应代码。

  5. Request合法域名配置。

    小程序中请求接口需要配置服务器域名。不同的AI类目对应的域名不一样,详情请参见访问域名

    以微信小程序为例,配置Request合法域名,如下图所示。合法域名

完整的示例可下载MiniprogramDemo

说明
  • 在微信小程序中,将代码中的<your appid>需要更换为您的appid。

  • 完整工程仅以银行卡识别(RecognizeBankCard)为例,如果调用其他算法,请参考注释进行相应代码修改。

  • utils/client.js文件中的accessKeyId、accessKeySecret,callRecognizeBankCard函数的endpoint、Action、API_VERSION参数及request_["ImageURL"]这一行代表业务参数。

    例如,您想使用通用分割能力,通过通用分割API文档可知该能力属于分割抠图类目(imageseg20191230),能力名称为SegmentCommonImage,您需要将endpoint改为imageseg.cn-shanghai.aliyuncs.com(注意该域名需要加入小程序白名单),Action改为SegmentCommonImage,API_VERSION为2019-12-30不用修改,request_["ImageURL"]参数名为ImageURL不用修改。获取结果的时候,需要获取ImageURL,其含义不是银行卡号,而是分割后的图片地址。

  • 本页导读 (1)
文档反馈