一次Bug调试的记录
简记
今天又双叒叕出了一个bug,前端使用vue+axios框架进行数据传输的时候需要判断请求数据的时候是否有session失效的情况,如果失效,需要将页面重定向到登录页面。
GET请求与缓存问题
axios.get("/user/getInfo")
这是第一个错误,测试的时候,先注销用户,注销用户后页面会跳转,然后点浏览器的回退,会发现上面的代码实际上不会再次执行,这个是get请求的特性,浏览器会将一个get请求当做是资源请求,因此这里当存在一个请求结果的时候就不会再次加载。实际上验证码后面加的随机数也是这个机制,但是实际程序设计的时候总是会遗忘呢。。。
Ajax请求的请求头判断方法
虽然这个方法我最终没有使用,但是还是在此记录一下, 说不定以后就能用了呢?
String requestedWith = ((HttpServletRequest) request).getHeader("X-Requested-With");
在网上参考的大部分都是使用这个方法进行判断,获取这个参数后判断其是否等于空,或者等于“XMLHttpRequest”,但是大概是我axios的配置问题,我并没有成功的使用这个方法判断是否是ajax请求,每次请求服务器都把他判断成了是http请求
邪道的方法
实际上,对于我的项目而言,只存在两种请求,一个是页面请求,一个就是axios的post或者是get请求,后端反正只要能区分开这两种请求就好了,那么不妨看看axios发送的报文里,header中到底包含了哪些内容
HttpServletRequest hq = (HttpServletRequest) request;
Enumeration<String> names = hq.getHeaderNames();
while(names.hasMoreElements()){
String name = names.nextElement();
System.out.println("--" + name + ":" + hq.getHeader(name));
}
对于一个正常的http请求而言,输出如下(“***”为隐藏)
--host:localhost:8090
--connection:keep-alive
--cache-control:max-age=0
--upgrade-insecure-requests:1
--user-agent:***
--accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
--sec-fetch-site:none
--sec-fetch-mode:navigate
--sec-fetch-user:?1
--sec-fetch-dest:document
--accept-encoding:gzip, deflate, br
--accept-language:zh-CN,zh;q=0.9,en;q=0.8
--cookie:***
--if-modified-since:Fri, 05 Jun 2020 06:46:05 GMT
对比由axios发送的post请求如下:
--host:localhost:8090
--connection:keep-alive
--content-length:0
--accept:application/json, text/plain, */*
--user-agent:***
--origin:http://localhost:8090
--sec-fetch-site:same-origin
--sec-fetch-mode:cors
--sec-fetch-dest:empty
--referer:http://localhost:8090/html/index.html
--accept-encoding:gzip, deflate, br
--accept-language:zh-CN,zh;q=0.9,en;q=0.8
--cookie:***
嗯。。。这里没有“X-Requested-With”啊,网上了解的结果是axios本身就不带,jquery是默认带着的,好吧,那只要找一个可以区分这两种请求的header的name就行了。
在此还是找一个我自己比较熟悉的"accept"作为区别这两个的name。
因此区分这两种请求的写法如下:
String accept = hq.getHeader("accept");
if (accept == null || accept.contains("application/json")) {
hp.getWriter().write("login failed"); // axios请求
}else{
hp.sendRedirect("/user/login.html"); // 正常http请求
}