解决方式
后端实现filter
Access-Control-Allow-Credentials设为true,表示接收前端的凭据
Access-Control-Allow-Origin上一个头为true,则这个头必须为域名,不能为*
实现filter可自动添加响应头,其他方式1、重写WebMvcConfigurerAdapter类,但对Credentials这个头的设置不生效。2、为每一个方法设置响应头,无法设置OPTION的响应头。3、为每个控制器加注解CrossOrigin,同样无法设置OPTION的响应头。
Http请求分为简单请求和复杂请求,GET和POST是简单请求,PUT和DELETE是复杂请求,复杂请求会先发一个OPTION嗅探请求,然后发送正式的请求。在发送OPTION请求时遇到问题,因为没有写控制器来处理OPTION请求,无法添加响应头,最后用实现Filter的方式解决问题。
@Component
public class CorsFilter implements Filter{
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.setHeader("Access-Control-Allow-Origin", "http://localhost:63342");
httpResponse.setHeader("Access-Control-Allow-Methods",
"POST, GET, OPTIONS, DELETE, PUT");
httpResponse.setHeader("Access-Control-Max-Age", "3600");
httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
httpResponse.setHeader("Access-Control-Allow-Headers",
"Content-Type, x-requested-with, X-Custom-Header, Authorization");
chain.doFilter(request, httpResponse);
// TODO Auto-generated method stub
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
}
前端ajax加上
用来传凭据,默认跨域是不传凭据的,后端shiro会认为没有登陆
xhrFields: {
//允许带上凭据
withCredentials: true
},