目录
那么跨域问题就是CORS全称Cross-Origin Resource Sharing,意为跨域资源共享。当一个资源去访问另一个不同域名或者同域名不同端口的资源时,就会发出跨域请求。如果此时另一个资源不允许其进行跨域资源访问,那么访问的那个资源就会遇到跨域问题。
URL | 是否跨域 | 原因 |
---|---|---|
https://www.baidu.com/more/index.html | 不跨域 | 三要素相同 |
https://map.baidu.com/ | 跨域 | 域名不同 |
http://www.baidu.com/index.html | 跨域 | 协议不同 |
https://www.baidu.com:81/index.html | 跨域 | 端口号不同 |
同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。
同源策略又分为以下两种:
CORS是一种W3C标准,定义了当产生跨域问题的时候,客户端与服务端如何通信解决跨域问题。实际上就是前后端约定好定义一些自定义的http请求头,让客户端发起请求的时候能够让服务端识别出来该请求是过还是不过。
浏览器将CORS请求分为简单请求和非简单请求:
简单请求必须满足以下两个条件:
不满足简单请求条件的就是非简单请求。针对非简单请求,浏览器会发起预检请求。预检请求的意思是当浏览器检查到你的页面含有跨域请求的时候,会发送一个OPTIONS请求给对应的服务器,以检测服务器是否允许当前域名的跨域请求。如果服务端允许该域名请求,则返回204或200状态码,浏览器接收到允许请求时候再继续发送对应的GET/POST/PUT/DELETE请求。同时服务器端也会告知浏览器预检请求的缓存时长是多少,在这个时间范围内,浏览器不会再次发起预检请求。
使用nginx代理
配置nginx.conf
... ...
location =/api {
proxy_pass http://ip:port$request_uri;
}
... ...
缺点
使用 filter 添加头信息(Spring MVC解决方案)
@Component
public class OriginFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException { }
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {undefined
HttpServletRequest httpServletRequest = WebUtils.toHttp(request);
HttpServletResponse httpServletResponse = WebUtils.toHttp(response);
httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE");
httpServletResponse.setHeader("Access-Control-Max-Age", "3600");
httpServletResponse.setHeader("Access-control-Allow-Origin", httpServletRequest.getHeader("Origin"));
httpServletResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control-Request-Headers"));
filterChain.doFilter(request, response);
}
@Override
public void destroy() { }
}
使用 @CrossOrigin 注解
直接在Controller类上加 @CrossOrigin 注解即可
缺点
使用proxy代理
优点
使用cors方案(Spring Boot解决方案)
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
super.addCorsMappings(registry);
registry.addMapping("/**")
.allowedHeaders("*")
.allowedMethods("POST","GET")
.allowedOrigins("*");
}
}
注意:使用此方法配置之后再使用自定义拦截器时跨域相关配置就会失效。