在开发web项目的时候,经常会碰到跨域的问题,常见的解决方式是后端配置一个支持的域名集合,或者支持域名的正则表达式集合,如果前端请求的header里面的origin的值和后端的配置相匹配,那么就在repsonse里面添加 Access-Control-Allow-Origin 为request重的origin的值,参考springcloud gateway的 DefaultCorsProcessor
@Nullable
public String checkOrigin(@Nullable String origin) {
if (!StringUtils.hasText(origin)) {
return null;
}
String originToCheck = trimTrailingSlash(origin);
if (!ObjectUtils.isEmpty(this.allowedOrigins)) {
if (this.allowedOrigins.contains(ALL)) {
validateAllowCredentials();
return ALL;
}
for (String allowedOrigin : this.allowedOrigins) {
if (originToCheck.equalsIgnoreCase(allowedOrigin)) {
return origin;
}
}
}
if (!ObjectUtils.isEmpty(this.allowedOriginPatterns)) {
for (OriginPattern p : this.allowedOriginPatterns) {
if (p.getDeclaredPattern().equals(ALL) || p.getPattern().matcher(originToCheck).matches()) {
return origin;
}
}
}
return null;
}
其中pattern的初始化为
private static Pattern initPattern(String patternValue) {
String portList = null;
Matcher matcher = PORTS_PATTERN.matcher(patternValue);
if (matcher.matches()) {
patternValue = matcher.group(1);
portList = matcher.group(2);
}
patternValue = "\\Q" + patternValue + "\\E";
patternValue = patternValue.replace("*", "\\E.*\\Q");
if (portList != null) {
patternValue += (portList.equals(ALL) ? "(:\\d+)?" : ":(" + portList.replace(',', '|') + ")");
}
return Pattern.compile(patternValue);
}
使用方式为:
spring:
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]':
allowedOriginPatterns: "*.test.com.cn"
allowedOrigins: "http://localhost:8000,http://127.0.0.1:8000"
allowedHeaders: "*"
allowedMethods: "*"