前后分离项目,前端为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官网
注意uni-app条件编译不需要在配置文件设置条件未MP-WEIXIN或者H5,在编译时自动判断。