http.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. // 封装axios请求
  2. import axios from 'axios'
  3. import CryptoJS from 'crypto-js';
  4. import {basePath} from '@/config/env'
  5. let onGetSession = false; //是否正在请求sessionkey
  6. const post = async (url, parms={}, isfromGetsskey) => {
  7. //这里是防止sessionkey接口很慢的情况下,其它正在排队的请求继续发送,导致短时间内多个重复请求(100ms一次)
  8. if(onGetSession && !isfromGetsskey){
  9. await _sleep(200);
  10. return post(url, parms)
  11. }
  12. let instance = axios.create({
  13. timeout: 1000 * 10,
  14. headers: {'Content-Type': 'application/x-www-form-urlencoded'}
  15. });
  16. let sskey = tool.getYdUserKey("session_key");
  17. let userId = tool.getYdUserKey('user_id') || 0;
  18. let xyy = tool.getYdUserKey('xyy') || 'zachhe';
  19. if(!sskey && !isfromGetsskey){
  20. sskey = await tool.getSessionKey(userId, xyy);
  21. }
  22. parms = Object.assign({
  23. user_id: userId,
  24. xyy: xyy,
  25. platform: 'web',
  26. session_key: sskey,
  27. session_from: 1,
  28. timestamp: Date.parse(new Date())/1000 + tool.timeSpace + ''
  29. }, parms)
  30. parms.sign = _hamcSha(url,parms,sskey);
  31. let qs = require('qs');
  32. let reqUrl = url.indexOf('http') > -1 ? url : basePath + url;
  33. return instance.post(reqUrl, qs.stringify(parms)).then(async function(res){
  34. if(!res.data || res.data.code === undefined || !res.data.msg){
  35. tool.$throw('结构体异常', parms, url, res.data);
  36. }
  37. let data = Object.assign({code:-1001, msg:'网络出问题了~'}, res.data);
  38. if(data.code === 7007){ //sessionkey过期
  39. tool.$throw('sskey过期', parms, url);
  40. if(isfromGetsskey){
  41. _dealSessionExpire()
  42. } else {
  43. delete parms.session_key;
  44. if(!onGetSession){ //前面没有正在请求的sessionkey
  45. onGetSession = true;
  46. let returnSskey = await tool.getSessionKey(parms.user_id,parms.xyy);
  47. onGetSession = false;
  48. if(!returnSskey) return {}; //没有获取到sesskey时,停止后面的请求,常见的场景是xyy过期
  49. return post(url, parms, true)
  50. } else { //前面有在请求的sessionkey
  51. await _sleep(100); //排队等100毫秒再去请求
  52. return post(url, parms)
  53. }
  54. }
  55. }
  56. if(data.code !== 0 && data.code !== 4004 && data.code !== 7007){
  57. if(data.code === 1 && data.msg === '参数不合法'){ //将参数不合法的请求上报
  58. tool.$throw('参数不合法', parms, url);
  59. let timeSpace = 0;
  60. if(res.headers.server_time){
  61. timeSpace = parseInt(res.headers.server_time) - parms.timestamp;
  62. }
  63. if(Math.abs(timeSpace) > 300){ //本地和服务器时间超过五分钟导致的参数不合法
  64. tool.timeSpace = timeSpace;
  65. delete parms.timestamp;
  66. return post(url, parms)
  67. }
  68. if(globalVue) globalVue.$message('服务异常,请稍后重试')
  69. } else if(globalVue){
  70. globalVue.$message(data.msg)
  71. }
  72. }
  73. if(data.code === 4004){ //user_id和xyy不匹配,最常见的是用户被设置成了广告用户,xyy发生变化
  74. tool.$throw('登录过期', parms, url);
  75. tool.toLogin();
  76. }
  77. return data;
  78. }).catch(res=>{
  79. tool.$throw(res, parms, reqUrl);
  80. if(isfromGetsskey){ //获取sessionkey超时
  81. tool.fetchSKtime++;
  82. if(tool.fetchSKtime < 3){ //最多请求三次,不行就出提示弹窗,常见场景有:1获取sessionkey超时,2按钮跳转时的事件上报(弱网下事件上报没完成页面就直接跳转走了,导致请求abort)
  83. return post(url, parms, true)
  84. } else {
  85. _dealSessionExpire()
  86. }
  87. } else if(globalVue){ //弱网下按钮跳转的事件上报被cancel时,不用出$message弹窗
  88. globalVue.$message('当前网络不给力,请稍后重试');
  89. }
  90. return {code: -1002, msg:'网络出问题了~'};
  91. });
  92. }
  93. //不带默认参数的请求,主要用于错误上报等
  94. const postOnly = async (url, parms={}, headers={}) => {
  95. let instance = axios.create({
  96. timeout: 1000 * 10,
  97. headers: {'Content-Type': 'application/x-www-form-urlencoded'}
  98. });
  99. let qs = require('qs');
  100. return instance.post(url, qs.stringify(parms)).then(function(res){
  101. return res.data;
  102. }).catch(res=>{
  103. let errObj = JSON.parse(parms.data);
  104. if(errObj.err_msg && window.ydStorage){
  105. ydStorage.setItem(errObj.err_msg, errObj, 3600*24*7, true);
  106. }
  107. })
  108. }
  109. const get = (url, parms={},headers={}) => {
  110. url += '?';
  111. for(let key in parms){
  112. url += key + '=' + parms[key] + '&';
  113. }
  114. let option = Object.assign({},headers);
  115. let instance = axios.create({
  116. timeout: 1000 * 10,
  117. headers: option
  118. });
  119. return instance.get(url).then(function(res){
  120. return res.data;
  121. }).catch(res=>{
  122. console.log('error',res);
  123. });
  124. }
  125. export default () => {
  126. if (typeof window.$http == 'undefined') {
  127. window.$http = {
  128. post: post,
  129. postOnly: postOnly,
  130. get: get
  131. }
  132. }
  133. }
  134. function _sortArgs(data){
  135. var args;
  136. var argsArr = [];
  137. for(args in data){
  138. if(data[args]==null || data[args]==undefined){
  139. data[args] = ""
  140. }
  141. if (args != "xyy" && args != "sign" && args != "content" && args != "feeling" && args != "nick" && args != "alipay_name"){
  142. argsArr.push(args);
  143. }
  144. }
  145. argsArr.sort();
  146. var argStr = "";
  147. for (var i = 0; i < argsArr.length;i++){
  148. var item = argsArr[i];
  149. argStr = argStr + item + "=" + data[item] + '&';
  150. }
  151. argStr=argStr.substring(0, argStr.length-1);
  152. argStr = encodeURIComponent(argStr);
  153. argStr = argStr.replace(/\(/g,"%28").replace(/\)/g,"%29").replace(/!/g, '%21').replace(/~/g, '%7E').replace(/\*/g, '%2A').replace(/'/g, '%27');
  154. return argStr
  155. }
  156. function _hamcSha(uri,data,sectionKoken){
  157. var url = encodeURIComponent(uri);
  158. var paramsStr = _sortArgs(data);
  159. var args = "POST&" + url + "&" + paramsStr;
  160. var hash = CryptoJS.HmacSHA1(args, sectionKoken);
  161. var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
  162. return hashInBase64
  163. }
  164. function _dealSessionExpire() {
  165. if(window.globalVue){
  166. globalVue.$confirm('很抱歉,访问出现错误', '提示', {
  167. confirmButtonText: '刷新页面',
  168. cancelButtonText: '重新登录',
  169. type: 'warning'
  170. }).then(() => {
  171. window.location.reload();
  172. }).catch(() => {
  173. tool.toLogin();
  174. });
  175. } else {
  176. tool.toLogin();
  177. }
  178. }
  179. function _sleep(interval) {
  180. return new Promise(resolve => {
  181. setTimeout(resolve, interval);
  182. })
  183. }