Http跨域请求及HttpSession同步终极手册
后端配置
继承org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport或者实现javax.servlet.Filter接口两种方式,springboot2.0以上才有WebMvcConfigurationSupport,之前为WebMvcConfigurerAdapter。
实现Filter接口后跨域配置的核心代码如下,其中HttpSession同步的重点在于response.setHeader("Access-Control-Allow-Credentials", "true");
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse;
String[] allowDomain = {"http://127.0.0.1:8848", "http://localhost:8848"}; Set<String> allowedOrigins = new HashSet<String>(Arrays.asList(allowDomain)); log.info("{}", request.getRequestURI()); String originHeader = request.getHeader("Origin"); if (allowedOrigins.contains(originHeader)) { response.setHeader("Access-Control-Allow-Origin", originHeader); response.setHeader("Access-Control-Allow-Credentials", "true"); response.setHeader("Access-Control-Allow-Methods", "POST, GET, PATCH, DELETE, PUT"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); } filterChain.doFilter(servletRequest, servletResponse); }
|
继承WebMvcConfigurationSupport后,跨域配置应当重写addCorsMappings,同步HttpSession的重点在于allowCredentials(true)
1 2 3 4 5 6 7 8 9
| @Override protected void _addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("") .allowedMethods("") .allowedHeaders("") .allowCredentials(true) .maxAge(3600); }
|
继承WebMvcConfigurationSupport后,同时可以配置拦截器,其中自定义拦截器MyInterceptor需要实现接口HandlerInterceptor
1 2 3 4 5 6
| @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new MyInterceptor()).addPathPatterns("/interceptor/test"); super.addInterceptors(registry); }
|
前端请求
前端请求代码如下,根据前端框架配置可能有所不同,但是HttpSession同步的关键在于xhrFields: {withCredentials: true},既为允许Http请求携带Cookie
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| $.ajax({ async:false, url: 'http://192.168.1.10:9119/session/test', data: { value: 'admin', key: "123456", }, xhrFields: { withCredentials: true }, crossDomain: true, success: function(data) { console.log(data) } });
|
浏览器设置
重点:以上配置全部正确无误后,HttpSession还是不能同步,这是因为浏览器限制。
Chrome与Edgd配置相似,因为同核。其它浏览器有待研究
- 在地址栏输入
chrome://flags、edge://flags
- 搜索
cookies
- 禁用下列两项
SameSite by default cookies = Disabled
Cookies without SameSite must be secure = Disabled
至止,前后端分离跨域请求HttpSession同步实现成功。