1.需求
前后端分离,想写一个过滤器通过token是否存在鉴别用户是否登录,没有登录则跳到登录界面
2.问题
ajax请求不能重定向,并且还存在跨域
3.解决
后端代码
1.跨域配置类
@Configuration
public class CrosConfig {
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*"); // 允许任何域名使用
corsConfiguration.addAllowedHeader("*"); // 允许任何头
corsConfiguration.addAllowedMethod("*"); // 允许任何方法(post、get等)
return corsConfiguration;
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", buildConfig()); // 对接口配置跨域设置
return new CorsFilter(source);
}
}
2.过滤器
response.setHeader(“Access-Control-Expose-Headers”, “*”);这句代码太重要了,不写它的话,前端那边获取不到自定义的响应头,知道的话就很简单,如果不知道…简直怀疑人生!
public class MyFilter extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//放行optoins请求
if (RequestMethod.OPTIONS.name().equals(request.getMethod())){
return true;
}
// 暴露哪些头部信息(因为跨域访问默认不能获取全部头部信息)
response.setHeader("Access-Control-Expose-Headers", "*");
String token = request.getHeader("Authorization");
//未登录
if ("null".equals(token) || StringUtils.isEmpty(token)) {
reDirect(request, response);
return false;
}
/*一系列操作*/
return true;
}
//对于请求是ajax请求重定向问题的处理方法
public void reDirect(HttpServletRequest request, HttpServletResponse response) throws IOException {
//获取当前请求的路径
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();
//如果request.getHeader("X-Requested-With") 返回的是"XMLHttpRequest"说明就是ajax请求,需要特殊处理
if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) {
//告诉ajax我是重定向
response.setHeader("REDIRECT", "REDIRECT");
//告诉ajax我重定向的路径
response.setHeader("CONTENTPATH", "登录界面url");
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
} else {
//不是ajax请求直接重定向
response.sendRedirect("登录界面url");
}
}
}
前端代码
1.这段代码为全局js代码,可以写个js文件,在需要的地方引入即可
var jqxhr;
//设置ajax请求完成后运行的函数,
$.ajaxSetup({
complete:function(){
if(jqxhr){
if("REDIRECT" == jqxhr.getResponseHeader("REDIRECT")){ //若HEADER中含有REDIRECT说明后端想重定向,
var win = window;
while(win != win.top){
win = win.top;
}
win.location.href = jqxhr.getResponseHeader("CONTENTPATH");//将后端重定向的地址取出来,使用win.location.href去实现重定向的要求
}
}
}
});
2.每次ajax请求都使用jqxhr接收返回值,如:
3.我这里ajax简单封装了一下,关于"X-Requested-With"请求头,我是自定义的,网上好像说jQery封装的ajax会有这个请求头,但是我后台一直获取不到,所以就自定义了,最后终于解决。
function myAjax(url,method,param,successHandle,errHandle){
var token = localStorage.getItem('token');
var myjqxhr = $.ajax({
url:baseURL + url,
method:method,
data:param,
success:successHandle,
error:errHandle,
headers:{"Authorization":token,'X-Requested-With':'XMLHttpRequest'}
})
return myjqxhr;
}