初始filter的代码如下:
public class LimitFilter implements Filter {
/**
* Default constructor.
*/
public LimitFilter() {
// TODO Auto-generated constructor stub
}
/**
* @see Filter#destroy()
*/
public void destroy() {
// TODO Auto-generated method stub
}
/**
* @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
// place your code here
// pass the request along the filter chain
HttpServletResponse httpServletResponse = (HttpServletResponse)response;
httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
httpServletResponse.setHeader("Access-Control-Allow-Headers", "User-Agent,Origin,Cache-Control,Content-type,Date,Server,withCredentials,AccessToken");
httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");
httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
httpServletResponse.setHeader("Access-Control-Max-Age", "1209600");
httpServletResponse.setHeader("Access-Control-Expose-Headers","accesstoken");
httpServletResponse.setHeader("Access-Control-Request-Headers","accesstoken");
httpServletResponse.setHeader("Expires","-1");
httpServletResponse.setHeader("Cache-Control","no-cache");
httpServletResponse.setHeader("pragma","no-cache");
if(!authenize()){//校验
//do something
return;
}
chain.doFilter(request, response);
}
/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
结果就算header加上Access-Control-Allow-Origin后,cors的配置仍然没有生效。
查了一下午,发现了问题所在,就是我拦截时连OPTIONS请求也一起拦截了。因为如果浏览器检查之后发现这是一个非简单请求,比如请求头含有accesstoken字段。这时候浏览器不会马上发送这个请求,而是有一个preflight,跟服务器验证的过程。浏览器先发送一个options方法的预检请求。而现在我连OPTIONS请求都拦截了,自然无法使cors生效。
下面是修改后的代码:
public class LimitFilter implements Filter {
/**
* Default constructor.
*/
public LimitFilter() {
// TODO Auto-generated constructor stub
}
/**
* @see Filter#destroy()
*/
public void destroy() {
// TODO Auto-generated method stub
}
/**
* @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
// place your code here
// pass the request along the filter chain
HttpServletResponse httpServletResponse = (HttpServletResponse)response;
httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
httpServletResponse.setHeader("Access-Control-Allow-Headers", "User-Agent,Origin,Cache-Control,Content-type,Date,Server,withCredentials,AccessToken");
httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");
httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
httpServletResponse.setHeader("Access-Control-Max-Age", "1209600");
httpServletResponse.setHeader("Access-Control-Expose-Headers","accesstoken");
httpServletResponse.setHeader("Access-Control-Request-Headers","accesstoken");
httpServletResponse.setHeader("Expires","-1");
httpServletResponse.setHeader("Cache-Control","no-cache");
httpServletResponse.setHeader("pragma","no-cache");
HttpServletRequest httpServletRequest = (HttpServletRequest)request;
if(!"OPTIONS".equals(httpServletRequest.getMethod())){//OPTIONS方法不要拦截,不然跨域设置不成功
if(!authenize()){//校验
//do something
return;
}
}
chain.doFilter(request, response);
}
/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
}
}