jquery 跨域 异步请求 自定义头部 预检请求 spring mvc拦截处理 实现token单点登录

被跨域搞死了,各种奇葩问题。

问题描述:跨域登录,生成token并保存到redis中,然后返回给客户端,客户端每次请求需要将token放到请求头中传给服务端,服务端使用过滤器处理跨域拦截,使用拦截器判断token有效性。问题来了,发来的请求总是获取不到头部信息,也就是取不到token值

解决:

网上说的过滤器需要做的处理都做了,代码如下:

		if (req instanceof HttpServletRequest && res instanceof HttpServletResponse) {
			HttpServletRequest request = (HttpServletRequest)req;
            HttpServletResponse response = (HttpServletResponse) res;
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Max-Age", "3600");
            response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE,JSONP");
            response.setHeader("Access-Control-Allow-Headers",
                "Origin, X-Requested-With, Content-Type, Accept,Authorization,X-CSRF-TOKEN");
 
            if(request.getMethod().equals(RequestMethod.OPTIONS.name())) {
            	response.setStatus(HttpStatus.OK.value());
            }
        }

        chain.doFilter(req, res);
为什么单独处理请求method是options的请求呢,因为异步请求中,只要你自定义了头部,默认浏览器都会先发送一个预检请求,看看服务端是否支持他真正的请求,比如我的真正的请求是get的登录请求,所以从浏览器里面可以看到,options真正的请求是get。

做了n多次测试都不好使,各种查资料,才发现问题的所在,上面的代码单独处理了options,浏览器只需要对options的返回结果,并不需要你重定向,所以上面的代码会报错302,无法重定向。

后来终于看到一位大哥写的,无需对options进行重定向,只需要return ; 回去就可以了,经测试真的没有问题了

最终代码如下:

		if (req instanceof HttpServletRequest && res instanceof HttpServletResponse) {
			HttpServletRequest request = (HttpServletRequest)req;
            HttpServletResponse response = (HttpServletResponse) res;
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Max-Age", "3600");
            response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE,JSONP");
            response.setHeader("Access-Control-Allow-Headers",
                "Origin, X-Requested-With, Content-Type, Accept,Authorization,X-CSRF-TOKEN");
            
            if(request.getMethod().equals(RequestMethod.OPTIONS.name())) {
            	response.setStatus(HttpStatus.OK.value());
            	return ;
            }
        }
        chain.doFilter(req, res);
当浏览器拿到了options的返回结果是200以后,会自动在发送真正的get请求,这时候的请求直接进入了拦截器,然后你就可以在拦截器里面获取自定义头部的token信息,并且验证token的有效性,进行相应的跳转了。


你可能感兴趣的:(java)