文章目录
- 一、跨域的产生
- 跨域的原因
- 二、解决方案
- 配置跨域
- 三、options请求是什么鬼?
- 3.1、为什么会出现options请求呢?
- 处理微服务开发调试
一、跨域的产生
跨域的原因
跨域是因为浏览器的同源策略限制,是浏览器的一种安全机制,服务端之间是不存在跨域的。
所谓同源
指的是两个页面具有相同的协议
、主机IP
和端口
,三者有任一不相同即会产生跨域。
二、解决方案
配置跨域
/**
* 跨域配置
*
*/
@Configuration
public class CorsConfig {
@Bean
public CorsWebFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
corsConfiguration.addAllowedOriginPattern("*");
corsConfiguration.setAllowCredentials(true);
source.registerCorsConfiguration("/**",corsConfiguration);
return new CorsWebFilter(source);
}
}
三、options请求是什么鬼?
3.1、为什么会出现options请求呢?
options
出现的情况只有两种:
- 1、获取目的资源所支持的通信方式
- 2、跨域请求中,
options
请求是浏览器自发起的preflight request(预检请求)
,以检测实际请求是否可以被浏览器接受。
preflight request
请求报文中有两个需要关注的首部字段:
(1)Access-Control-Request-Method
:告知服务器实际请求所使用的HTTP方法;
(2)Access-Control-Request-Headers
:告知服务器实际请求所携带的自定义首部字段。
- 只有复杂请求才会进行
preflight request(预检请求)
符合以下任一情况的就是复杂请求:
- 1.使用方法
put
或者delete
;- 2.发送
json
格式的数据(content-type: application/json)- 3.请求中带有
自定义头部
;
处理微服务开发调试
GateWay
调试场景,开发环境只想启动相应的后端模块接口进行调试,但是因为跨域所以需要每次启动GateWay
模块加上模块
在接口请求中我们总会自定义请求头做
token
,但是暂浏览器的preflight request(预检请求)
中的OPTIONS
只会携带自定义的token
字段但不会带相应的值,导致跨域以及报错,
所以要处理跨域以及在SpringSecurity
的认证过滤器链中需要过滤掉OPTIONS
- 上面配了跨域后,再在认证放通即可
-
SpringSecurity
的登录认证在放行OPTIONS
即可,不然就自己加拦截器放在WebMvcConfig
中
public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws IOException, ServletException {
String originalHeader=request.getHeader("Origin");
if(ObjectUtils.isNotEmpty(originalHeader)){
response.addHeader("Access-Control-Allow-Origin",originalHeader);
response.addHeader("Access-Control-Allow-Credentials","true");
response.addHeader("Access-Control-Allow-Methods","POST,GET,OPTIONS,DELETE,PUT");
response.addHeader("Access-Control-Allow-Headers",request.getHeader("Access-Control-Request-Headers"));
}
if(().equals(request.getMethod())){
response.setStatus(HttpServletResponse.SC_OK);
return;
}
...
}
- 最后结果
直连本地,其他连接开发环境接口
Access-Control-Allow-Credentials
- 响应头表示是否可以将对请求的响应暴露给页面。浏览器仅在响应标头
Access-Control-Allow-Credentials
的值为true
的情况下将响应暴露给前端的JavaScript
代码。
Credentials
可以是cookies、authorization headers
或 TLS client certificates
。
- 当作为对
预检请求的响应
的一部分时,这能表示是否真正的请求可以使用credentials
。 - 若一个对资源的请求带了
credentials
,如果这个响应头没有随资源返回,响应就会被浏览器忽视,不会返回到 web 内容。 -
Credentials
必须在前后端都被配置(即Access-Control-Allow-Credentials header
和 XHR 或 Fetch request 中都要配置)才能使带credentials
的CORS
请求成功。