现象
GET
请求正常返回
POST
请求返回
403 Forbidden
gateway access 日志:
2022-01-11 11:56:52,488 : 10.0.16.132:15362 - - [11/Jan/2022:11:56:52 +0800] "GET /landing-page/experience-train-enroll/status?phoneNumber=15074470123 HTTP/1.1" 200 85 44 ms
2022-01-11 11:56:52,589 : 10.0.16.132:15362 - - [11/Jan/2022:11:56:52 +0800] "POST /landing-page/verify/code HTTP/1.1" 403 0 12 ms
请求路径为:【浏览器】==》【apache】==》【gateway】==》【后端 web 应用】
注意:【apache】会将接收到的 HTTPS
请求,转换为 HTTP
请求转发到【gateway】
跟踪 DefaultCorsProcessor
类的 process()
方法
package org.springframework.web.cors.reactive;
public class DefaultCorsProcessor implements CorsProcessor {
public boolean process(@Nullable CorsConfiguration config, ServerWebExchange exchange) {
// 1. 判断是否是跨域请求,如果不是直接返回 true
if (!CorsUtils.isCorsRequest(request)) {
return true;
return handleInternal(exchange, config, preFlightRequest);
protected boolean handleInternal(ServerWebExchange exchange,
CorsConfiguration config, boolean preFlightRequest) {
// 2. 获取请求头 Origin 的值
String requestOrigin = request.getHeaders().getOrigin();
String allowOrigin = checkOrigin(config, requestOrigin);
// 4. 为 null 表示不满足条件,返回 403
if (allowOrigin == null) {
logger.debug("Reject: '" + requestOrigin + "' origin is not allowed");
rejectRequest(response);
return false;
return true;
// 3. 校验 requestOrigin 是否符合跨域的配置
protected String checkOrigin(CorsConfiguration config, @Nullable String requestOrigin) {
return config.checkOrigin(requestOrigin);
// 5. 设置 http 响应状态码为 403
protected void rejectRequest(ServerHttpResponse response) {
response.setStatusCode(HttpStatus.FORBIDDEN);
public abstract class CorsUtils {
// 跨域请求需要满足下面两个条件
// 1. 包含 Origin 请求头
// 2. request 的 schema:host:port 和 origin 一致
public static boolean isCorsRequest(ServerHttpRequest request) {
return request.getHeaders().containsKey(HttpHeaders.ORIGIN) && !isSameOrigin(request);
因为【apache】会把 HTTPS
协议请求转换为 HTTP
协议请求,而同源策略要求协议相同。
所以转化后的请求不再是同源请求,因此需要在 application.yml
文件中新增如下配置。
spring:
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]':
allowedOrigins: ["https://xxx-gamma.wumii.net"] # 此行配置是重点
allowedMethods:
- GET
- POST
- HEAD
- PUT
- DELETE
allowedHeaders: '*'
allowCredentials: true
add-to-simple-url-handler-mapping: true
以支持跨域请求。
GET 请求为什么不会自动加上 Origin 请求头?