前后分离项目,前端为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;
- // #endif
- return 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 H5
- uni.redirectTo({
- url: $mUtils.objParseUrlAndParam($mRoutesConfig.loginPwd.path, query)
- })
- // #endif
-
-
- //#ifdef MP-WEIXIN
- uni.redirectTo({
- url: $mUtils.objParseUrlAndParam($mRoutesConfig.login.path, query)
- })
- // #endif
-
- } else {
-
- //#ifdef H5
- uni.redirectTo({
- url: $mUtils.objParseUrlAndParam($mRoutesConfig.loginPwd.path, query)
- })
- // #endif
-
- //#ifdef MP-WEIXIN
- uni.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();
- // 状态码为200
- if (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条件编译不需要在配置文件设置条件未MP-WEIXIN或者H5,在编译时自动判断。