拦截器解决跨域问题

拦截器解决跨域问题

注:本文是用SpringBoot + Dubbo搭建的分布式工程,前后端分离,前端工程和后端工程的端口号不同,所以产生了前端请求跨域问题。

拦截器定义

注意,前端的请求域名如果是80端口,直接指定为"http://localhost",其他端口才具体指定。
如果你的项目有多个客户端域名,那么可以指定一个数组,如下:

		// 设置允许多个域名请求
		String[] allowDomains = {"http://localhost:8081","http://localhost:8082"};
		Set<String> allowOrigins = new HashSet<String>(Arrays.asList(allowDomains));
		String originHeads = httpServletRequest.getHeader("Origin");
		if(allowOrigins.contains(originHeads)){
		}
// 跨域请求处理拦截器
@Component
public class CorsInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 指定前端的请求域名
        String allowDomain = "http://localhost";
        String originHeads = request.getHeader("Origin");
        if(allowDomain.equals(originHeads)){
            //设置允许跨域的配置
            // 这里填写你允许进行跨域的主机ip(正式上线时可以动态配置具体允许的域名和IP)
            response.setHeader("Access-Control-Allow-Origin", originHeads);
        }

        response.setHeader("Access-Control-Allow-Credentials", "true");

        response.setHeader("Access-Control-Allow-Headers",
                "Content-Type,Content-Length, Authorization, Accept,X-Requested-With");

        response.setHeader("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");

        response.setHeader("X-Powered-By", "Jetty");

        String method = request.getMethod();
        if (method.equals("OPTIONS")) {

            response.setStatus(200);

            return false;
        }
        return true;
    }
}

注意:拦截器与过滤器功能相似,使用相同逻辑的过滤器也能解决跨域问题,如下:

@Component
public class CorsFilterConfig implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
		
        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest request = (HttpServletRequest) req;
        response.setHeader("x-frame-options", "SAMEORIGIN");
        // 不使用*,自动适配跨域域名,避免携带Cookie时失效
        String origin = request.getHeader("Origin");
        if (StringUtils.isNotBlank(origin)) {
            response.setHeader("Access-Control-Allow-Origin", origin); }
        // 自适应所有自定义头
        String headers = request.getHeader("Access-Control-Request-Headers");
        if(StringUtils.isNotBlank(headers)) {
            response.setHeader("Access-Control-Allow-Headers", headers);
            response.setHeader("Access-Control-Expose-Headers", headers);
        }
        // 允许跨域的请求方法类型
        response.setHeader("Access-Control-Allow-Methods", "*");
        // 预检命令(OPTIONS)缓存时间,单位:秒
        response.setHeader("Access-Control-Max-Age", "3600");
        // 明确许可客户端发送Cookie,不允许删除字段即可
        response.setHeader("Access-Control-Allow-Credentials", "true");
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
    }
}

拦截器配置

注意:如果项目中还有其他拦截器,应该配置在CorsInterceptor 之后,保证CorsInterceptor 解决跨域请求问题后,才放行到其他拦截器。

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {

    @Autowired
    private CorsInterceptor corsInterceptor;

    /*
    * 在配置类中指定拦截器的相关配置*/
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
    	// 拦截所有请求
        String[] addPaths = {
                "/**"
        };
        String[] excludePaths = {
                "/**/*.css", "/**/*.js", "/**/*.png", "/**/*.jpg", "/**/*.jpeg"
        };
        registry.addInterceptor(corsInterceptor).addPathPatterns(addPaths).excludePathPatterns(excludePaths);
    }
}

前端请求配置

跨域问题是前后端一起解决的,如果项目使用到Cookie,前端请求函数也要做相应的配置。
如果使用Vue axios,配置如下:

// 允许携带cookie
axio.withCredentials = true;
axio.defaults.withCredentials = true;

如果使用AJAV,配置如下:

$.ajax({
    url: SERVER_URL + "/ticket/check",
    type: "post",
    xhrFields: {
        withCredentials: true  //解决跨服务传递时不传递cookie的问题,允许携带证书
    },
    crossDomain: true,  //允许跨域
    contentType:'application/json',
    data:JSON.stringify({}),
    dataType: "json",
    success:function (resp) {
    },
});
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值