Spring Boot项目中实现跨域访问

1,260 阅读2分钟

注意:此总结基于Spring Boot 2.0.0.RELEASE

跨域相关知识学习

掘金上一位大佬分享的关于跨域的总结,总结得非常详细到位了,文章条理清晰,既有理论讲解,又有代码例举,强烈推荐阅读

juejin.cn/post/684490…

Spring Boot项目中如何实现跨域访问

我们采用 CORS的方式来实现跨越访问,所以需要注意,IE 浏览器不能低于 IE10

为了实现跨域访问,我们要做的事情就是在响应头中添加允许跨域的相关字段,主要是以下几个

  • Access-Control-Allow-Origin,设置需要放行的其它源的地址,多个以逗号隔开,通常仅设置当前请求源的地址

    Access-Control-Allow-Origin: http://x.x.x.x:1,http://x.x.x.x:2
    
  • Access-Control-Max-Age,设置该Preflight请求缓存时间,在此时间内,该请求不需要再次发起Preflight请求,从而节省服务器性能,提升效率,单位为秒

    Access-Control-Max-Age: 21600
    
  • Access-Control-Allow-Headers,设置请求头中允许的字段,如果请求头中有一些特殊的字段,例如自定义字段,则响应头中需要设置此字段,否则不能请求成功,如无则不用设置,多个以逗号隔开

    Access-Control-Allow-Headers: token,timestamp
    
  • Access-Control-Allow-Methods,设置允许的请求方式,如无限制,可以不设置,多个以逗号隔开

    Access-Control-Allow-Methods: GET,POST
    

实现思路也很简单,我们需要做一个拦截器,这个拦截器的作用就是将我们要设置的字段添加进响应头中,然后通过java-base configuration的方式将拦截器添加进MVC的拦截器链中,把握这个思路,在非Spring Boot工程中,也可以很快地找到实现的方法。

  • 拦截器

    import org.springframework.web.servlet.HandlerInterceptor;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.util.Arrays;
    import java.util.HashSet;
    import java.util.Set;
    
    /**
     * 用于支持跨域的拦截器
     */
    public class CrossOriginInterceptor implements HandlerInterceptor {
    
        /**
         * 允许跨域的域名信息集合
         */
        private Set<String> allowedOrigins;
    
        public CrossOriginInterceptor(String[] origins) {
            allowedOrigins = new HashSet<>(Arrays.asList(origins));
        }
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
            // 若允许跨域的域名信息集合中包含请求的域名信息,则在返回消息头中添加Access-Control-Allow-Origin
            String requestOrigin = request.getHeader("origin");
            if (allowedOrigins.contains(requestOrigin)) {
                response.setHeader("Access-Control-Allow-Origin", requestOrigin);
                response.setHeader("Access-Control-Max-Age", "21600");
            }
            return true;
        }
    }
    
  • java-base configuration

    import com.dongrui.study.mockserver.interceptors.CrossOriginInterceptor;
    import org.springframework.beans.factory.annotation.Value;
    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;
    
    @Configuration
    public class WebAppConfigurator implements WebMvcConfigurer {
    
        @Value("${crossOrigin.origins}")
        private String[] origins;
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            // 添加用于支持跨域的拦截器
            InterceptorRegistration registration = registry.addInterceptor(new CrossOriginInterceptor(origins));
            registration.addPathPatterns("/**");// 所有路径都被拦截
            registration.excludePathPatterns("/", "/login", "/error", "/static/**", "/logout");// 添加不拦截路径
        }
    }