request.js 5.29 KB
import getPrivateKey from './getPrivateKey'
import config from '../../config.js'
import trimObject from './utils/trimObject.js'
import queryString from './utils/query-string/query-string.js'
const crypto = require('./utils/cryptojs/cryptojs.js');
import MD5 from './utils/md5/md5.js'
import udid from './utils/udid.js'

const request = (methods = 'GET') => {
  return async (options = {}) => {
    try {
      let pk = await getPrivateKey();
      options.pk = pk;
      options.methods = methods;
      return new Promise(function (resolve, reject) {
        sendRequest(resolve, reject, options);
      })
    } catch (e) {
      return new Promise(function (resolve, reject) {
        if (!e || !e.isPrivatekeyError) {
          reject(e);
        }
        sendRequest(resolve, reject, options);
      })
    }
  }
}

const getGlobalData = () => {
  const app = getApp();
  let globalData;
  if (app && app.globalData) {
    // 原生小程序的 globalData 获取方式
    globalData = app && app.globalData;
  } else {
    // Taro 下 globalData 获取方式
    globalData = app && app.props && app.props.globalData;
  }
  return globalData;
}

/**
 * 请求参数相关
 */
const handleParam = (params) => {
  let globalData = getGlobalData();
  getUid(params);
  getUdid(params);
  const userInfo = getStorageUserInfo();
  const session_key = userInfo && userInfo.session_key ? globalData.userInfo.session_key : '';
  const publicParams = _publicParams();
  let newParams = {
    ...params,
    ...publicParams,
  };
  if (session_key) {
    newParams.session_key = session_key;
  }
  return newParams;
}

const getUdid = (params) => {
  params.udid = udid.get();
}

const getUid = (params) => {
  const userInfo = getStorageUserInfo();
  if (params && !params.hasOwnProperty('uid')) {
    // 判断 globalData 是否包含 uid
    let uid = userInfo && userInfo.uid ? userInfo.uid : 0;
    if (uid !== 0) {
      params.uid = uid;
    }
  }
}

const _publicParams = () => {
  let screen_size;
  let os_version;
  try {
    let res = wx.getSystemInfoSync();
    screen_size = res.windowWidth + 'x' + res.windowHeight;
    os_version = res.version;
  } catch (e) {}
  let publicParams = {
    ...config.apiParams,
    v: '7',
    screen_size,
    // os_version
  }
  return publicParams;
}

const _signParam = (params, encode = false) => {
  const resultParams = _signResultParams(params, encode);
  const resultString = queryString.stringify(resultParams, { encode });
  return resultString;
}

const _signResultParams = (params, encode = false) => {
  let allParams = trimObject(params);	// 去除首尾空格
  let paramsPair = queryString.stringify(allParams, { encode: false });
  let client_secret = MD5(paramsPair);
  delete allParams.private_key;
  const resultParams = Object.assign(allParams, { client_secret });
  return resultParams;
}

/**
 * 请求头相关
 */
const handleHeader = (options, newParams) => {
  let p2SecretKey = options.pk;
  if (p2SecretKey === '') {
    p2SecretKey = getYHStorageSync("p2SecretKey", 'request')
  }
  let param = _signParam(newParams, false);
  let resultString = ''
  if (p2SecretKey) {
    resultString = crypto.HMAC(crypto.SHA256, param, p2SecretKey, "")
  }
  const session_key = newParams.session_key ? newParams.session_key : '';
  let header = {
    'x-yoho-verify': resultString,
    'Cookie': 'JSESSIONID=' + session_key,
    'Cookies': 'JSESSIONID=' + session_key,
  }
  return header;
}

/**
 * 发送请求
 */
const sendRequest = (resolve, reject, options) => {
  // 处理请求参数
  const newParams = handleParam(options.params);
  const resultParams = _signResultParams(newParams, options.encode);
  // 处理请求头
  const header = handleHeader(options, newParams);
  // path 路径
  let url = options.url;
  if (options.path) {
    url = url + options.path;
  }
  // 请求
  wx.request({
    url: url,
    data: resultParams,
    header: header,
    method: options.methods,
    success: function(res) {
      const statusCode = res.statusCode;
      const errMsg = res.errMsg;
      const data = res.data;
      if (data && (data.code == 200 || data.code == 301) && data.data) {
        resolve(data.data);
      } else {
        const code = data.code ? data.code: res.statusCode;
        const message = data.message ? data.message: res.errMsg;
        reject({ code, message });
      }
    },
    fail: function (err) {
      const code = err.code ? err.code : 800;
      const message = err.message ? err.message : '';
      reject({ code, message });
    },
    complete: options.complete, // 无论成功还是失败, 都会调用,可以用于取消 loading 等
  })
}

const getYHStorageSync = (key, fromPage) => {
  try {
    let res = wx.getStorageSync(key);
    return res;
  } catch (e) {
    wx.reportAnalytics('ufo_get_storage_error', {
      key: key,
      error: e.message,
      error_code: e.code,
      from_page: fromPage,
    });
    return null;
  }
}

const getStorageUserInfo = () => {
  const globalData = getGlobalData();
  if (globalData.userInfo.length > 0) {
    return globalData.userInfo;
  } else {
    return getYHStorageSync('userInfo');
  }
}

export const GET = request('GET');
export const POST = request('POST');
export const PUT = request('PUT');
export const DELETE = request('DELETE');
// export const UPLOAD_LOG = uploadLogData('POST')
// export const APP_REPORT = appReport('POST')