公众号merlinsea
- 背景:在我们平时开发前后台分离的项目的时候,前端的资源是一个url域名(比如www.home.cn),后台的函数功能是另一个URL域名(比如 api/v1/pri/product),因此存在前台域名和后台功能函数域名不同源的情况,这种情况会导致通过后台url返回的数据无法在前台进行展示。
- 跨域报的错误是
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
- 如何避免这种情况,就需要配置跨域策略:
- 就是在响应报文的响应头中加入Access-Control-Allow-Origin = origin的key-value,这个key-value表示后端返回的内容可以允许任何前端页面访问。
- 在后端代码中编写拦截器,用于拦截返回的response
public class CorsInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //orgin表示接受响应结果可以在任意域名中展示,也可以指定前端资源的域名 response.setHeader("Access-Control-Allow-Origin", request.getHeader("origin")); //该字段可选,是个布尔值,表示是否可以携带cookie response.setHeader("Access-Control-Allow-Credentials", "true"); response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS"); response.setHeader("Access-Control-Allow-Headers", "*"); //这里可以不加,但是其他语言开发的话记得处理options请求 /** * 非简单请求是对那种对服务器有特殊要求的请求, * 比如请求方式是PUT或者DELETE,或者Content-Type字段类型是application/json。 * 都会在正式通信之前,增加一次HTTP请求,称之为预检。浏览器会先询问服务器,当前网页所在域名是否在服务器的许可名单之中, * 服务器允许之后,浏览器会发出正式的XMLHttpRequest请求 */ if(HttpMethod.OPTIONS.toString().equals(request.getMethod())){ return true; } return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } }
- 将拦截器通过配置文件类配置出来并交由spring进行管理
@Configuration public class InterceptorConfig implements WebMvcConfigurer { //跨域拦截器 @Bean CorsInterceptor corsInterceptor(){ return new CorsInterceptor(); } @Override public void addInterceptors(InterceptorRegistry registry) { /** * 用于表示后端的哪些接口要被跨域拦截器拦截,这里是后端的全部接口都要被拦截 */ registry.addInterceptor(corsInterceptor()).addPathPatterns("/**"); WebMvcConfigurer.super.addInterceptors(registry); } }