|
|
接口调用及其引用方法
更新时间:2018-05-03 10:33:34 更新人员:叶洋  文档状态:
摘要
-
转换成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)
})
}
-
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)
}
-
数据签名
应用背景:
接口对外来的请求数据需要做一次数据合法性认证,因此对所传递的数据需要进行签名。而签名具有时效性,需要注意本机的时间是否为标准的北京时间。
参考方法:
/**
* 数据签名加密
* @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
}
-
接口调用
应用背景:
系统接口的调用遵循了一些规则,例如传参的方法,请求头部内需要什么数据,签名通过什么方式传送,用户身份如何识别等等问题,因此综合本系统一系列情况而封装了接口调用方法。
参考方法:
/**
* 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)
})
})
}
-
配置常量定义
以上方法内部用到一些常量,统一解释如下:
// 接口基础地址
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
}
|