springmvc源码学习(二十八)解决跨域的几种方式

springmvc源码学习(二十八)解决跨域的几种方式,第1张

springmvc源码学习(二十八)解决跨域的几种方式

目录
  • 前言
  • 一、跨域
  • 二、解决
    • 1、CorsFilter
    • 2、实现 WebMvcConfigurer
    • 3、实现 HandlerInterceptor


前言


一、跨域

是由于浏览器的同源策略限制,同源策略是一个重要的安全策略,会阻止一个域的javascript脚本和另外一个域的内容进行交互。一个请求url的协议(protocol)、域名(host)、端口(port)都要相同,其中有一个不同都会产生跨域问题。

二、解决 1、CorsFilter

(1)自定义 CustomCorsFilter

public class CustomCorsFilter extends CorsFilter {
    private CorsProps corsProps;

    public CustomCrosFilter(CorsConfigurationSource configSource, CorsProps corsProps) {
        super(configSource);
        this.corsProps = corsProps;

    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {


        response.setHeader("Access-Control-Allow-Origin", corsProps.getOrigin());
        response.setHeader("Access-Control-Allow-Credentials", corsProps.getCredentials());
        response.setHeader("Access-Control-Allow-Methods", corsProps.getMethods());
        response.setHeader("Access-Control-Allow-Headers", corsProps.getHeaders());
        filterChain.doFilter(request, response);
    }

(2)CorsProps

@ConfigurationProperties(prefix = "cors")
@Data
public class CorsProps {
    private String origin = "*";
    private String credentials = "true";
    private String methods = "POST, GET, PUT, DELETE, OPTIONS";
    private String headers = "Content-Type, Data-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With, Accept, DataType, responseType";
    private String maxAge = "300";
}

(3)CorsAutoConfiguration

@Configuration
@ConditionalOnProperty(prefix = "cors",matchIfMissing = true,value = "enabled")
@Slf4j
public class CorsAutoConfiguration {
    @Autowired
    private CorsProps corsProps;

    @Bean
    public CustomCorsFilter corsFilter() {
        UrlbasedCorsConfigurationSource source = new UrlbasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", buildConfig());
        return new CustomCorsFilter(source,crosProps);
    }

    private CorsConfiguration buildConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        // Access-Control-Allow-Origin
        corsConfiguration.addAllowedOrigin(corsProps.getOrigin());
        corsConfiguration.addAllowedHeader(corsProps.getHeaders());
        // Access-Control-Allow-Methods
        corsConfiguration.addAllowedMethod(corsProps.getMethods());
        // 预检请求的有效期 Access-Control-Max-Age
        corsConfiguration.setMaxAge(Long.valueOf(corsProps.getMaxAge()));
        // 是否支持安全证书 Access-Control-Allow-Credentials
        corsConfiguration.setAllowCredentials(Boolean.valueOf(corsProps.getCredentials()));
        return corsConfiguration;
    }

    @Bean
    public FilterRegistrationBean corsFilterRegistrationBean(CustomCorsFilter corsFilter) {
        FilterRegistrationBean frb = new FilterRegistrationBean();
        //设置最高优先级
        frb.setOrder(Ordered.HIGHEST_PRECEDENCE);
        frb.setFilter(corsFilter);
        frb.addUrlPatterns("/*");
        frb.setName("customCorsFilter ");
        return frb;
    }
2、实现 WebMvcConfigurer
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

   @Autowired
    private CorsProps corsProps;
    
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowCredentials(Boolean.getBoolean(corsProps.getCredentials()))
                .allowedOrigins(corsProps.getOrigin())
                .allowedMethods(corsProps.getMethods().split(","))
                .allowedHeaders(corsProps.getHeaders());
    }

}
3、实现 HandlerInterceptor

(1)CorsHandlerInterceptor

public class CorsHandlerInterceptor implements HandlerInterceptor {

    private CorsProps corsProps;

    public CorsHandlerInterceptor(CorsProps corsProps) {
        this.corsProps = corsProps;
    }

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        response.setHeader("Access-Control-Allow-Origin", corsProps.getOrigin());
        response.setHeader("Access-Control-Allow-Credentials", corsProps.getCredentials());
        response.setHeader("Access-Control-Allow-Methods", corsProps.getMethods());
        response.setHeader("Access-Control-Allow-Headers", corsProps.getHeaders());
       
        return true;
    }
}

(2)注册拦截器

@Configuration
public class CorsInterceptorConfig implements WebMvcConfigurer {

    @Autowired
    private CorsProps corsProps;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 添加拦截器,配置拦截地址
        registry.addInterceptor(new CorsHandlerInterceptor(corsProps))
                .addPathPatterns("/**");;
    }
}

其他方式也可以实现,如通过 @CrossOrigin 进行更细粒度的控制跨域 ,通过 nginx 进行代理转发等。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5692273.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存