解决Springboot+ajax跨域及每次请求sessionId不一样的问题

1、问题复现:

项目中后端使用Springboot搭建,使用Shiro做安全管理。前后端分离后,前端使用ajax访问服务端程序。在未做任何处理前,ajax报错:

Access to XMLHttpRequest at 'http://127.0.0.1:8080/login/checkLogin' from origin 
'http://localhost:63342' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' 
header is present on the requested resource.

明显是跨域问题引起的浏览器无法正常接收服务端的响应。服务端对响应头信息做出统一拦截修改后,跨域问题解决。但shiro的授权管理

Subject currentUser = SecurityUtils.getSubject();
currentUser.isAuthenticated(); // 每次请求,都是返回false

isAuthenticated()每次请求都返回false

排除半天,发现每次请求的sessionId均不一样。想还是ajax的跨域问题没有完全解决。进一步解决后,记录如下:

  • 问 题 1 : a j a x 跨 域 问 题 \color{#FF3030}{问题1:ajax跨域问题} 1ajax
  • 问 题 2 : a j a x 每 次 访 问 后 端 , s e s s i o n I d 均 不 同 \color{#FF3030}{问题2:ajax每次访问后端,sessionId均不同} 2ajax访sessionId

2、问题解决

前端:

ajax需要添加以下内容:

$.ajax({
            url:BASE_URL + "/login/checkLogin",
            // 添加下列内容解决sessionId不一问题
            xhrFields: {
                withCredentials: true
            },
            data:{},
            success:function (resp) {

            }
        })

后端

后端有几种配置方式,本质一样,任选之一即可:

方式(一)

使用springboot自带的解决跨域的配置,最简单高效。创建以下配置类

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 CorsConfig {
	private CorsConfiguration buildConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*"); 
        corsConfiguration.addAllowedHeader("*"); 
        corsConfiguration.addAllowedMethod("*"); 
        corsConfiguration.setAllowCredentials(true);
        return corsConfiguration;
    }
    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", buildConfig()); 
        return new CorsFilter(source);
    }
}
方式(二)

用传统springMVC自定义拦截器。创建拦截器:

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
/**
 * 解决跨域请求
 * @author sirm 2020.2.6
 *
 */
public class CrossDomainInterceptor implements HandlerInterceptor{
	
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
	    response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
	    response.setHeader("Access-Control-Allow-Methods", "*");
	    response.setHeader("Access-Control-Allow-Headers", "*");
		response.setHeader("Access-Control-Allow-Credentials", "true");
		return true;
	}
}

添加拦截器配置(原始添加方式)

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import com.sirm.pro.interceptor.CrossDomainInterceptor;
 
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //注册拦截器
        InterceptorRegistration crossDomain = registry.addInterceptor(new CrossDomainInterceptor());
        //所有路径都被拦截
        crossDomain.addPathPatterns("/**");                   
    }
}
方式(三)

如果没有使用springboot,而是传统SSM框架,同方式二,可以把配置写入springmvc的配置xml中

首先还是自定义一个拦截器

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
/**
 * 解决跨域请求
 * @author sirm 2020.2.6
 *
 */
public class CrossDomainInterceptor implements HandlerInterceptor{
	
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
	    response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
	    response.setHeader("Access-Control-Allow-Methods", "*");
	    response.setHeader("Access-Control-Allow-Headers", "*");
		response.setHeader("Access-Control-Allow-Credentials", "true");
		return true;
	}
}

在springmvc的配置xml中配置拦截器

<mvc:interceptors>
		<mvc:interceptor>
			<mvc:mapping path="/**" /> 
            
			<bean class="com.***.****.CrossDomainInterceptor">bean>
		mvc:interceptor>
	mvc:interceptors>

你可能感兴趣的:(Java随笔)