后台已经设置允许跨域,但是前台依然报错。
public class CorsFilter implements Filter{
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse resp = (HttpServletResponse) servletResponse;
// 告诉浏览器允许所有的域访问
resp.addHeader("Access-Control-Allow-Origin", "*");
// 允许带有cookie访问
resp.addHeader("Access-Control-Allow-Credentials", "true");
// 告诉浏览器允许跨域访问的方法
resp.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
// 告诉浏览器允许带有所有的请求头访问
resp.addHeader("Access-Control-Allow-Headers", "*");
// 告诉浏览器缓存OPTIONS预检请求1小时,避免非简单请求每次发送预检请求,提升性能
resp.addHeader("Access-Control-Max-Age", "3600");
chain.doFilter(request, resp);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
}
面对CORS的限制,将如何解决呢
CORS
标准新增了一组 HTTP
头字段(Access-Control-Allow-Origin
),允许服务器声明哪些源通过浏览器有权限访问哪些资源。另外,规范要求,对那些可能对服务器数据产生副作用的 HTTP
请求方法(特别是 GET
以外的 HTTP
请求,或者搭配某些 MIME
类型的 POST
请求),浏览器必须首先使用 OPTIONS
方法发起一个预检请求(preflight request
),从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的 HTTP
请求。在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(包括 Cookies
和 HTTP
认证相关数据)。
问题就出在这个OPTIONS请求方法中,因为之前为了安全起见,有人在web.xml中配置了,禁止了OPTIONS的请求方法,现在需要把该配置放开,注销OPTIONS的配置即可,如下:
<!-- 禁止不安全的http方法 -->
<security-constraint>
<web-resource-collection>
<web-resource-name>fortune</web-resource-name>
<url-pattern>/*</url-pattern>
<http-method>PUT</http-method>
<http-method>DELETE</http-method>
<http-method>HEAD</http-method>
<!-- <http-method>OPTIONS</http-method> -->
<http-method>TRACE</http-method>
<http-method>PATCH</http-method>
</web-resource-collection>
<auth-constraint/>
</security-constraint>