文 档 中 心 / Document Center
搜索 管理中心
壹川接口文档V3
接口调用及其引用方法
更新时间:2018-05-03 10:33:34   更新人员:叶洋   文档状态:
摘要
  1. 转换成Unicode内容
    应用背景:
    将字符串中的中文字符转换为unicode编码,避免因不同的系统及编译环境在对中文加密时产生结果不一致的错误影响。
    参考方法:
    /**
     * 转换成Unicode内容
     * @param s   传入的字符串
     * @returns {*}
     */
    function toUnicode (s) {
      return s.replace(/([\u4E00-\u9FA5]|[\uFE30-\uFFA0])/g, (newStr) => {
        return '\\u' + newStr.charCodeAt(0).toString(16)
      })
    }
    
  2. BASE64编码
    应用背景:
    原始数据内不一定但可能会出现一些符号字符,而有些符号字符可能会导致一些加密结果不一致的情况,为避免此类情况发生,需要将数据转换为无符号的字符串,因此采用前置base64加密方法。
    参考方法:
    /**
     * 转换成Base64
     * @constructor
     */
    function Base64 () {
      // private property
      let _keyStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
      // public method for encoding
      this.encode = function (input) {
        let output = ''
        let chr1, chr2, chr3, enc1, enc2, enc3, enc4
        let i = 0
        input = utf8Encode(input)
        while (i < input.length) {
          chr1 = input.charCodeAt(i++)
          chr2 = input.charCodeAt(i++)
          chr3 = input.charCodeAt(i++)
          enc1 = chr1 >> 2
          enc2 = ((chr1 & 3) << 4) | (chr2 >> 4)
          enc3 = ((chr2 & 15) << 2) | (chr3 >> 6)
          enc4 = chr3 & 63
          if (isNaN(chr2)) {
            enc3 = enc4 = 64
          } else if (isNaN(chr3)) {
            enc4 = 64
          }
          output = output + _keyStr.charAt(enc1) + _keyStr.charAt(enc2) + _keyStr.charAt(enc3) + _keyStr.charAt(enc4)
        }
        return output
      }
      // public method for decoding
      this.decode = function (input) {
        let output = ''
        let chr1, chr2, chr3
        let enc1, enc2, enc3, enc4
        let i = 0
        input = input.replace(/[^A-Za-z0-9]/g, '')
        while (i < input.length) {
          enc1 = _keyStr.indexOf(input.charAt(i++))
          enc2 = _keyStr.indexOf(input.charAt(i++))
          enc3 = _keyStr.indexOf(input.charAt(i++))
          enc4 = _keyStr.indexOf(input.charAt(i++))
          chr1 = (enc1 << 2) | (enc2 >> 4)
          chr2 = ((enc2 & 15) << 4) | (enc3 >> 2)
          chr3 = ((enc3 & 3) << 6) | enc4
          output = output + String.fromCharCode(chr1)
          if (enc3 !== 64) {
            output = output + String.fromCharCode(chr2)
          }
          if (enc4 !== 64) {
            output = output + String.fromCharCode(chr3)
          }
        }
        output = utf8Decode(output)
        return output
      }
    
      // private method for UTF-8 encoding
      let utf8Encode = function (string) {
        string = string.replace(/\r\n/g, '\n')
        let utftext = ''
        for (let n = 0; n < string.length; n++) {
          let c = string.charCodeAt(n)
          if (c < 128) {
            utftext += String.fromCharCode(c)
          } else if ((c > 127) && (c < 2048)) {
            utftext += String.fromCharCode((c >> 6) | 192)
            utftext += String.fromCharCode((c & 63) | 128)
          } else {
            utftext += String.fromCharCode((c >> 12) | 224)
            utftext += String.fromCharCode(((c >> 6) & 63) | 128)
            utftext += String.fromCharCode((c & 63) | 128)
          }
        }
        return utftext
      }
    
      // private method for UTF-8 decoding
      let utf8Decode = function (utftext) {
        let string = ''
        let i = 0
        let c = 0
        // let c1 = 0
        let c2 = 0
        let c3 = 0
        while (i < utftext.length) {
          c = utftext.charCodeAt(i)
          if (c < 128) {
            string += String.fromCharCode(c)
            i++
          } else if ((c > 191) && (c < 224)) {
            c2 = utftext.charCodeAt(i + 1)
            string += String.fromCharCode(((c & 31) << 6) | (c2 & 63))
            i += 2
          } else {
            c2 = utftext.charCodeAt(i + 1)
            c3 = utftext.charCodeAt(i + 2)
            string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63))
            i += 3
          }
        }
        return string
      }
    }
    
    /**
     * base64Encode
     * @param str
     */
    export function base64Encode (str) {
      let base = new Base64()
      return base.encode(str)
    }
    
    /**
     * base64Decode
     * @param str
     */
    export function base64Decode (str) {
      let base = new Base64()
      return base.decode(str)
    }
    
  3. 数据签名
    应用背景:
    接口对外来的请求数据需要做一次数据合法性认证,因此对所传递的数据需要进行签名。而签名具有时效性,需要注意本机的时间是否为标准的北京时间。
    参考方法:
    /**
     * 数据签名加密
     * @param paramList
     * @returns {string}
     * @author yang,bin
     */
    export function autograph (paramList) {
      const currDay = new Date().toLocaleDateString().replace(/\/(\d)\//, '/0$1/').replace(/\/(\d)$/, '/0$1').replace(/\//g, '')
      let param = []
      for (let i in paramList) {
        let mvkey = typeof i !== 'undefined' ? i.toString().trim() : ''
        let mvval = ''
        if (typeof paramList[i] !== 'undefined') {
          if (paramList[i] instanceof Object) {
            mvval = JSON.stringify(paramList[i])
          } else {
            mvval = paramList[i].toString().trim()
          }
        }
        if (mvkey !== '' && mvval !== '') {
          param.push(`${mvkey}=${mvval}`)
        }
      }
    
      param.push(`merch_key=${XAPIKEY}`)
    
      param.sort((a, b) => {
        return a > b ? 1 : -1
      })
    
      let cssstr = param.join('&')
      cssstr = toUnicode(cssstr)
      cssstr = base64Encode(cssstr)
      let signstr = md5(cssstr)
      signstr = md5(`${signstr}.${XAPIKEY}`)
      signstr = md5(signstr + currDay)
    
      return signstr
    }
    
  4. 接口调用
    应用背景:
    系统接口的调用遵循了一些规则,例如传参的方法,请求头部内需要什么数据,签名通过什么方式传送,用户身份如何识别等等问题,因此综合本系统一系列情况而封装了接口调用方法。
    参考方法:
    /**
     * axios 自定义封装
     * @param url
     * @param types 判断是否公共接口调用
     * @param configs
     * @returns {Promise}
     * @author yang,bin
     */
    export function apirq (url, configs, types) {
      let configsDefalut = {
        baseURL: API,
        method: 'get',
        data: {},
        urlparams: [] // 自定义路由参数,根据参数进行替换路由
      }
      let typeDefault = []
      if (types) {
        typeDefault = types.split(',')
      }
      configs = Object.assign(Object.assign({}, configsDefalut), configs)
      if (configs.data['signature'] !== undefined) {
        delete configs.data['signature']
      }
      configs.data['signature'] = autograph(configs.data)
      for (let t of configs.urlparams) {
        url = url.replace(`:${t}`, configs.data[t]).replace(`<${t}>`, configs.data[t])
        delete configs.data[t]
      }
      delete configs.urlparams
      configs.url = url
      let headers = ACCESSHEADER
      // 如果是公共接口,则不需要access-token
      const actoken = sessionStorage.getItem('accessToken') // 判断是否已经存在accessToken
      if (typeDefault.indexOf('noauth') === -1 && actoken !== null) {
        headers['access-token'] = actoken
      }
      headers['Content-Type'] = 'application/json; charset=utf-8'
      configs.headers = headers
      if (configs.method === 'get') {
        configs.params = configs.data
        delete configs.data
      }
    
      return new Promise((resolve, reject) => {
        axios(configs).then((response) => {
          for (let i = 0; i < typeDefault.length; i++) {
            switch (typeDefault[i]) {
              case 'login':
                sessionStorage.setItem('accessToken', response.headers['access-token'])
                break
            }
          }
          resolve(response.data)
        }).catch((e) => {
          reject(e)
        })
      })
    }
    
  5. 配置常量定义
    以上方法内部用到一些常量,统一解释如下:
    // 接口基础地址
    export const API = 'http://*****.***/api/'  
    // 调用接口版本
    export const XAPIVER = '1.0'  
    // 商户密钥
    export const XAPIKEY = '2Io8************************NNUL' 
    // 标准请求头参数
    export const ACCESSHEADER = {   
      'x-api-ver': XAPIVER,
      'x-api-key': XAPIKEY
    }
    
本书创建于 2018-03-30 12:03:13 ?如有疑问,请联系技术人员