jquery 跨域 异步请求 自定义头部 预检请求 spring mvc拦截处理 实现token单点登录
2018-02-05 10:37
886 查看
被跨域搞死了,各种奇葩问题。
问题描述:跨域登录,生成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,无法重定向。
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的有效性,进行相应的跳转了。
问题描述:跨域登录,生成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的有效性,进行相应的跳转了。
相关文章推荐
- 分别使用FlyJSONP和JQuery实现跨域的异步请求 .
- 分别使用FlyJSONP和JQuery实现跨域的异步请求
- 模拟http或https请求,实现ssl下的bugzilla登录、新增BUG,保持会话以及处理token
- ajax前置处理实现异步请求session过期时跳转登录页面
- JQuery中使用Ajax实现诸如登录名检测等异步请求Demo
- 通过Spring MVC 的自定义拦截器实现灵活的登录拦截
- Struts 通过拦截器实现登录后跳转到登录前页面 处理普通Http请求和Ajax请求时拦截配置
- jQuery中JSONP结合Spring MVC实现跨域请求
- 分别使用FlyJSONP和JQuery实现跨域的异步请求
- Spring MVC结合jQuery实现跨域请求
- 通过Spring MVC 的自定义拦截器实现灵活的登录拦截
- 前端控制器是整个MVC框架中最为核心的一块,它主要用来拦截符合要求的外部请求,并把请求分发到不同的控制器去处理,根据控制器处理后的结果,生成相应的响应发送到客户端。前端控制器既可以使用Filter实现(Struts2采用这种方式),也可以使用Servlet来实现(spring MVC框架)。
- spring mvc 实现http异步请求处理
- 过滤器实现登录拦截需要注意的问题(AJAX请求的处理)
- jQuery异步请求(如getJSON)跨域解决方案
- spring mvc 第二天【注解实现springmvc Handler处理ajax简单请求 的配置】
- jquery实现post异步请求
- Shiro 处理ajax请求 拦截登录超时---解决!
- Spring MVC 异步处理请求,提高程序性能
- Spring MVC 异步处理请求,提高程序性能