注:本文仅供学习参考,如有错漏,望指正!
今天验证一个微服务框架的适用性,框架集成的Swagger发请求时提示如下异常,借此机会对CORS(跨域资源共享)了解一二:
Failed to fetch.
Possible Reasons:
CORS
Network Failure
URL scheme must be “http” or “https” for CORS request
关于CORS(跨域资源共享)的详细解读:
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS
问题记录及解决方案
1、异常截图
2、产生异常的原因
下面这篇博文对跨域问题产生原因总结的简单易懂,直接参考↓
以下截图来自博文:【项目实战】-Spring-Cloud跨域方案汇总_springcloud跨域解决方案-CSDN博客
3、解决方案
- 方案一:在gateway中添加WebFilter,如(以下代码缺乏安全性,具体原因参考下文
关于附带身份凭证的请求与通配符 ):
/** * CORS 过滤 * * @author ahsz */ @Slf4j @RequiredArgsConstructor @Order(Ordered.HIGHEST_PRECEDENCE) @Configuration(proxyBeanMethods = false) public class SecurityRuleFilter implements WebFilter { @Override @SuppressWarnings("all") public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) { /** * 增加CORS * 解决前端登录跨域的问题 */ ServerHttpRequest request = exchange.getRequest(); if (CorsUtils.isCorsRequest(request)) { log.info("添加CORS……"); ServerHttpResponse response = exchange.getResponse(); HttpHeaders headers = response.getHeaders(); headers.add("Access-Control-Allow-Origin", "*"); headers.add("Access-Control-Allow-Methods", "*"); headers.add("Access-Control-Max-Age", "3600"); headers.add("Access-Control-Allow-Headers", "*"); // 扩展自定义header项 // headers.add("Access-Control-Expose-Headers", "Content-Disposition"); // if (request.getMethod() == HttpMethod.OPTIONS) { // response.setStatusCode(HttpStatus.OK); // return Mono.empty(); // } } return chain.filter(exchange); } }
- 方案二:修改gateway网关配置信息,如下:
spring: cloud: gateway: globalcors: cors-configurations: '[/**]': allowedOrigins: "*" allowedHeaders: "*" allowedMethods: "*"
4、正常运行结果
关于CORS的一些杂记
下文仅为重要内容,详情见:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS
1、关于附带身份凭证的请求与通配符
在响应附带身份凭证的请求时:
- 服务器不能将
Access-Control-Allow-Origin 的值设为通配符“* ”,而应将其设置为特定的域,如:Access-Control-Allow-Origin: https://example.com 。 - 服务器不能将
Access-Control-Allow-Headers 的值设为通配符“* ”,而应将其设置为标头名称的列表,如:Access-Control-Allow-Headers: X-PINGOTHER, Content-Type - 服务器不能将
Access-Control-Allow-Methods 的值设为通配符“* ”,而应将其设置为特定请求方法名称的列表,如:Access-Control-Allow-Methods: POST, GET
对于附带身份凭证的请求(通常是
这是因为请求的标头中携带了
另外,响应标头中也携带了
2、CORS涉及到的请求头
HTTP 响应标头字段
- Access-Control-Allow-Origin
响应标头中可以携带一个
Access-Control-Allow-Origin: <origin> | *
例如,为了允许来自
Access-Control-Allow-Origin: https://mozilla.org Vary: Origin
如果服务端指定了具体的单个源(作为允许列表的一部分,可能会根据请求的来源而动态改变)而非通配符“
- Access-Control-Expose-Headers
译者注:在跨源访问时,
Access-Control-Expose-Headers: <header-name>[, <header-name>]*
例如:
Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header
这样浏览器就能够通过
- Access-Control-Max-Age
Access-Control-Max-Age: <delta-seconds>
- Access-Control-Allow-Credentials
Access-Control-Allow-Credentials: true
- Access-Control-Allow-Methods
Access-Control-Allow-Methods: <method>[, <method>]*
有关预检请求的示例已在上方给出,包含了将此请求头发送至浏览器的示例。
- Access-Control-Allow-Headers
Access-Control-Allow-Headers: <header-name>[, <header-name>]*
HTTP 请求标头字段
本节列出了可用于发起跨源请求的标头字段。请注意,这些标头字段无须手动设置。当开发者使用
- Origin
Origin: <origin>
origin 参数的值为源站 URL。它不包含任何路径信息,只是服务器名称。
注:
注意,在所有访问控制请求中,
- Access-Control-Request-Method
Access-Control-Request-Method: <method>
- Access-Control-Request-Headers
Access-Control-Request-Headers: <field-name>[, <field-name>]*