本文最后更新于:2020年12月30日 凌晨
问题 在页面上要使用 Ajax
请求去获取另外一个服务的数据,由于浏览器的 同源策略 ,所以直接请求会得到一个 Error
。
1 Failed to load https://www.baidu.com/: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
大概就是这样的一个错误,关键词是 Access-Control-Allow-Origin ,一般出现这个都是跨域问题。
解决方案 解决跨域问题的方式有很多,但这里之说 Cors 的方案。
在后台添加一个 Filter
过滤器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 public class CustomCorsFilterConfig implements Filter { @Override public void init (FilterConfig filterConfig) { } @Override public void doFilter (ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { String allowOrigin = "*" ; String allowMethods = "GET,POST,PUT,DELETE,OPTIONS" ; String allowHeaders = "Content-Type,X-Token,Authorization" ; String allowCredentials = "true" ; String origin = request.getHeader("Origin" ); response.setHeader("Access-Control-Allow-Origin" , origin == null ? allowOrigin : origin); response.setHeader("Access-Control-Allow-Methods" , allowMethods); response.setHeader("Access-Control-Allow-Credentials" , allowCredentials); response.setHeader("Access-Control-Allow-Headers" , allowHeaders); if ("OPTIONS" .equals(request.getMethod())) { response.setStatus(HttpServletResponse.SC_OK); return ; } filterChain.doFilter(request, response); } @Override public void destroy () { } }
在 web.xml
文件中添加拦截器配置(注:如果可能就配置成第一个 Filter
)
1 2 3 4 5 6 7 8 9 <filter > <filter-name > customCorsFilterConfig</filter-name > <filter-class > CustomCorsFilterConfig</filter-class > </filter > <filter-mapping > <filter-name > customCorsFilterConfig</filter-name > <url-pattern > /*</url-pattern > </filter-mapping >
Spring Web 的解决方案 配置一个每次请求都过滤一次的 Filter
就好了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 @Configuration public class CorsConfig { @Bean public OncePerRequestFilter corsFilter () { return new OncePerRequestFilter () { @Override protected void doFilterInternal (HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String allowOrigin = "*" ; String allowMethods = "GET,POST,PUT,DELETE,OPTIONS" ; String allowHeaders = "Content-Type,X-Token,Authorization" ; String allowCredentials = "true" ; String origin = request.getHeader("Origin" ); response.setHeader("Access-Control-Allow-Origin" , origin == null ? allowOrigin : origin); response.setHeader("Access-Control-Allow-Methods" , allowMethods); response.setHeader("Access-Control-Allow-Credentials" , allowCredentials); response.setHeader("Access-Control-Allow-Headers" , allowHeaders); if ("OPTIONS" .equals(request.getMethod())) { response.setStatus(HttpServletResponse.SC_OK); return ; } filterChain.doFilter(request, response); } }; } }
使用示例 下面是一些简单的使用 fetch
进行跨域请求的示例:
那么,之后在前端跨域请求的时候就可以愉快地玩耍啦(v^_^)v