解决Axios跨域请求时session不一致
1、原因
这个问题的产生关系到会话保持的原理:当浏览器第一次请求服务器时,服务器会为其创建一个session对象,每个session对象有一个自己的唯一id作为自己的标识。服务器为了判断下次请求的是不是同一个浏览器,会把这个sessionId放到cookie中,以cookie的形式返回给浏览器,并暂时存储在浏览器中。这样,只要浏览器不关闭,再去访问服务器时,就会自动带上这个sessionId,服务器再次接收请求时,就会去获取这个sessionId,并与服务器内存中存在的sessionId比对,验证通过就说明这个用户之前访问过,不用为其重新分配新的session对象,就达到了会话的保持。如果以上理解不了的请先自行查阅什么是session和cookie。
所以维持会话的一个关键点其实是携带了sessionId的这个cookie。出现了session不一致的问题,那多半就是跨域请求时没有携带cookie,或者服务器不允许你携带cookie~
根据线索去查阅资料后得知:XMLHttpRequest 存在一个名为
withCredentials
的属性,该属性默认值为false,在发送同源请求时该属性不起作用,但在作跨域请求时,它的作用就非常大了:
true:在跨域请求时,会携带用户凭证,也就是cookie;
false:在跨域请求时,不会携带用户凭证,并且返回的response里也会忽略cookie。
2.解决方法
锁定了问题的原因,问题自然也就迎刃而解了:
1.设置前端请求的withCredentials属性为true,让其请求时携带cookie;
在axios请求时携带该属性:
this.$axios.get('/api/test',{withCredentials : true}).then((res)=>{
console.log(res)
})
或者在main.js中作全局的配置,一劳永逸~
import Vue from 'vue';
import axios from 'axios';
//请求默认地址
axios.defaults.baseURL = "http://127.0.0.1:8081/";
//请求超时时间
axios.defaults.timeout = 10000;
//post请求头
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
//设置cross跨域 并设置访问权限 允许跨域携带cookie信息
axios.defaults.withCredentials=true;
2.设置后台的withCredentials属性为true,让其允许前端携带cookie请求,并在响应时也携带cookie。
在springboot构建的项目中,如果用的@CrossOrigin注解,为其加上allowCredentials参数,作局部的处理:@CrossOrigin(allowCredentials="true")
(在@CrossOrigin源码中默认为)。
或者使用拦截器或过滤器作全局的配置:
拦截器:
package com.example.pahms.Inteceptor;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class CORSInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
response.setHeader("Access-Control-Expose-Headers", "token");// 服务器 headers 白名单,可以让客户端进行访问操作的属性
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
return true;
}
}
过滤器:
package com.example.pahms.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@Configuration
public class GlobalCorsConfig {
@Bean
public CorsFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin("*");
config.setAllowCredentials(true);
config.addAllowedMethod("*");
config.addAllowedHeader("*");
UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
configSource.registerCorsConfiguration("/**", config);
return new CorsFilter(configSource);
}
}
推荐阅读
-
解决Axios跨域请求时session不一致
-
解决vue中的跨域问题(Axios请求)
-
跨域请求的解决方案和使用axios让请求头部携带含有登录标记的cookie的方法
-
解决vue+springboot前后端分离项目,前端跨域访问sessionID不一致导致的session为null问题
-
React如何解决fetch跨域请求时session失效问题
-
解决使用elementUI框架el-upload跨域上传时session丢失问题
-
解决跨域,session不一致问题
-
关于axios进行跨域请求时的问题处理
-
前端笔记知识点整合之服务器&Ajax(下)数据请求&解决跨域&三级联动&session&堆栈
-
完美解决axios跨域请求出错的问题