当前位置:首页 » 《关注互联网》 » 正文

前端请求后台接口失败处理逻辑

23 人参与  2024年04月15日 15:05  分类 : 《关注互联网》  评论

点击全文阅读


前后分离项目,前端为uni-app(vue2),后台为java

后台api设置存在问题,部分公共接口为开放非登录用户访问权限

导致前台打开首页后立即跳转到登录提示页

怀疑是开了uni-app开发代理服务器,导致访问的代理服务器地址被拦截:

http://localhost:3030/api/bms/getPostPageList?page=1&limit=12&hot=1

由于不能通过单步执行,查找执行过程,只能在拦截代码中盲猜,始终未找到匹配的代码过程:

import Vue from 'vue'import App from './App'import store from './store'import * as Db from './common/db.js'import $AppEntryController from './AppEntryController.js'import * as $apis from './apis/index.js'import $mRouter from './common/router.js'import $mUtils from './common/utils.js'import $mConfig from "./config/index.config.js"import $mAssetsPath from './config/assets.config.js'import $mRoutesConfig from './config/routes.config.js'import $mConstDataConfig from './config/constData.config.js'import $modalHelper from './common/modalHelper.js'import mPageView from "./components/m-page-view/m-page-view.vue"Vue.component("yzb-page", mPageView)const prePage = ()=>{let pages = getCurrentPages();let prePage = pages[pages.length - 2];    // #ifdef H5    return prePage;    // #endifreturn prePage.$vm;}Vue.prototype.$mPage ={prePage};Vue.config.productionTip = false;Vue.prototype.$AppEntryController = $AppEntryController;Vue.prototype.$store =store;Vue.prototype.$apis = $apis;Vue.prototype.$mRouter = $mRouter;Vue.prototype.$mUtils = $mUtils;Vue.prototype.$mConfig = $mConfig;Vue.prototype.$mAssetsPath = $mAssetsPath;Vue.prototype.$mRoutesConfig = $mRoutesConfig;Vue.prototype.$mConstDataConfig = $mConstDataConfig;Vue.prototype.$modalHelper = $modalHelper;Vue.prototype.$db = Db;import GoEasy from "./lib/goeasy-2.4.7.min.js";const goEasy = GoEasy.getInstance({host:"hangzhou.goeasy.io",//应用所在的区域地址: 【hangzhou.goeasy.io |singapore.goeasy.io】appkey:"BC-88a9b720d97c4de88eefd2d64daf3fd0",// common key,    modules:["im"],// true表示支持通知栏提醒,false则表示不需要通知栏提醒    allowNotification:true //仅有效于app,小程序和H5将会被自动忽略});Vue.prototype.GoEasy = GoEasy;Vue.prototype.goEasy = goEasy;$mRouter.beforeEach((navType, to) => {if (to.route === undefined) throw ("路由钩子函数中没有找到to.route对象,路由信息:" + JSON.stringify(to));console.log("进入路由过滤器")console.log("to=",to)if (to.route.path === $mRoutesConfig.login.path && store.getters.hasLogin) {uni.redirectTo({url: $mUtils.objParseUrlAndParam($mRoutesConfig.main.path, to.query)})return;}// 过滤需要权限的页面if (to.route.requiresAuth) {if (store.getters.hasLogin) {// 已经登录uni[navType]({url: $mUtils.objParseUrlAndParam(to.route.path, to.query)})} else {// 登录成功后的重定向地址和参数let query = {redirectUrl: to.route.path,...to.query}// 没有登录 是否强制登录?if (store.state.forcedLogin) {//#ifdef H5uni.redirectTo({url: $mUtils.objParseUrlAndParam($mRoutesConfig.loginPwd.path, query)})// #endif//#ifdef MP-WEIXINuni.redirectTo({url: $mUtils.objParseUrlAndParam($mRoutesConfig.login.path, query)})// #endif} else {//#ifdef H5uni.redirectTo({url: $mUtils.objParseUrlAndParam($mRoutesConfig.loginPwd.path, query)})// #endif//#ifdef MP-WEIXINuni.redirectTo({url: $mUtils.objParseUrlAndParam($mRoutesConfig.login.path, query)})// #endif}}} else {uni[navType]({url: $mUtils.objParseUrlAndParam(to.route.path, to.query)})}})App.mpType = 'app'const app = new Vue({store,...App})app.$mount()Vue.prototype.formatDate = function (t) {    t = t || Date.now();    let time = new Date(t);    let str = time.getMonth() < 9 ? ('0' + (time.getMonth() + 1)) : (time.getMonth() + 1);    str += '-';    str += time.getDate() < 10 ? ('0' + time.getDate()) : time.getDate();    str += ' ';    str += time.getHours();    str += ':';    str += time.getMinutes() < 10 ? ('0' + time.getMinutes()) : time.getMinutes();    return str;}// 控制全局日志开关// console.log = (function (oriLogFunc) {//   return function () {//     //判断配置文件是否开启日志调试//     if (!true) {//       try{//         oriLogFunc.call(console, ...arguments);//       }catch(e){//         console.error('console.log error', e);//       }//     }//   }// })(console.log);

重新查看uni-app发送http请求的代码段,发现在后台返回401时,代码直接跳转到登录流程:

import store from "@/store"function HTTP(obj, config) {let defaultConfig = {isRes: false,loading: false}config = { ...defaultConfig,...config}// 如果需要显示loading,mask防止点击穿透config.loading && uni.showLoading({title: '加载中',mask: true});return new Promise((resolve, reject) => {let options = {url: "",method: "GET",data: {},dataType: "json",header: {"content-type": "application/json","X-requested-With": "XMLHttpRequest",// 模拟用户登录//"X-Access-Token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2OTQ1MjM5NDEsInVzZXJuYW1lIjoiYWRtaW4ifQ.iGxw-j0uNi-rY96KuP9B4Jgx-t-Uk2mYZxVWMb7ySbo"},success: (res) => {//console.log("HTTP请求结果:",res)//console.log("resolve:",resolve)uni.hideLoading();// 状态码为200if (res.statusCode == 200) {let data = res.data;//自动校验用户是否登录过期if (data.code == "01") {store.dispatch("reLogin");return;}//返回 { code:10000,msg:"消息",data:[] }if (config.isRes) {resolve(data)}// 返回 data:[]else {if (data.code == "200") {//console.log("data对象:",data)resolve(data.result||true)} else {wx.showToast({title: data.message,icon: "none",duration: 2000})reject(data.message);}}}else if(res.statusCode == 401) {store.dispatch("reLogin");return;} else {reject("HTTP:状态码异常!");}},fail: (err) => {uni.hideLoading();uni.showToast({title: "网络异常,请稍后再试!",icon: "none",})reject("网络异常,请稍后再试!");},complete: () => {}}options = { ...options,...obj};const OPENID = uni.getStorageSync("openId");const Token=uni.getStorageSync("token");// const location=uni.getStorageSync("location");// if(location){// //所有接口带上当前位置信息// options["data"]["latitude"] = location.latitude;// options["data"]["longitude"] = location.longitude;// options["data"]["pcitycode"] = location.pcitycode;// }console.log("Token==="+Token);if (OPENID) options["header"]["openId"] = OPENID;if (Token) options["header"]["X-Access-Token"] = Token;if (options.url && options.method) {wx.request(options);} else {wx.showToast({title: 'HTTP:缺失参数',icon: "none",duration: 2000})}})}export default {GET(url, data = {}, config) {return HTTP({url,data,method: "GET"}, config);},POST(url, data = {}, config) {return HTTP({url,data,method: "POST"}, config);},POSTformdata(url, data = {}, config) {return HTTP({url,data,method: "POST"}, config);}}

这个过程对用户不友好,应提示用户未登录无法查看数据,让用户确认跳转还是留在原始位置。

解决办法是,使用wx.showModal(显示选择的对话框-带按钮),添加如下代码:

else if(res.statusCode == 401) {let res_message = res.data.message // 因为wx.showModal也有res,需要另存变量名wx.showModal({  title: '是否需要登录?',  content: '提示:'+res_message,  complete: (res) => {if (res.cancel) {reject(res_message);}if (res.confirm) {store.dispatch("reLogin");}  }})// 这不是正常的promise流程,添加这段代码的人不是原作者// store.dispatch("reLogin");// return;}

为了适应h5页面或小程序,添加条件编译:

效果:

 点确定则跳转到登录页面,点取消则留在当前页面。

参考:

https://www.cnblogs.com/guanxinjing/p/17337941.html

跨端兼容 | uni-app官网

注意uni-app条件编译不需要在配置文件设置条件未MP-WEIXIN或者H5,在编译时自动判断。


点击全文阅读


本文链接:http://zhangshiyu.com/post/95585.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1