一般来说使用@CrossOrigin即可解决问题,但也有时会出现不起效果的时候。
在今天出现的一个bug中,通过浏览器访问和postman访问都正常,但前端依然出现跨域,其用的是Vue+axios的解决方案,在搜索了一下,发现axios在跨域时有个特点:
访问跨域资源时总是先发一个Method是OPTIONS 的包给服务端,检查一下服务器能不能正常跨域访问。而后才发真正的请求。
[解决方案](https://www.cnblogs.com/6324/p/7609117.html)
而解决方案就是针对第一次请求,返回给它跨域的头即可,不要添加其他的header。
@WebFilter(urlPatterns = "/*",filterName = "channelFilter")
public class ChannelFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response1 = (HttpServletResponse) response;
HttpServletRequest request1 = (HttpServletRequest) request;
response1.setHeader("Access-Control-Allow-Origin", "*");
response1.setHeader("Access-Control-Allow-Credentials", "true");
response1.setHeader("Access-Control-Allow-Methods", "*");
response1.setHeader("Access-Control-Allow-Headers", "Content-Type,Access-Token");
response1.setHeader("Access-Control-Expose-Headers", "*");
if (request1.getMethod().equals( RequestMethod.OPTIONS.toString())){
System.out.println("-----检查------");
return;
//如果是OPTIONS,返回跨域头就行,不进入下一层拦截器,也无需进入servlet容器,更不需要进入相应的Controller类
}
chain.doFilter(request, response);
}
@Override
public void destroy() {
}
}
@SpringBootApplication
@ServletComponentScan//添加扫描
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
之前的ajax访问springboot没出现过这种问题,可能是axios特有的吧。
从结果上看,正确的处理是第一次查看服务器状态返回需要从检测到方法为OPTIONS即返回,不需要去做其他的响应。
而对于@CrossOrigin来说,它做的只是给每个请求的response都添加了跨域头部而已,所有的访问都有其响应,而显然第一次访问是没有对应的响应的。
所以这次跨域问题是由于前端不需要我的处理响应,而同时我找不到需要响应的方法导致的跨域报错?