[TOC]
# 版本
> Kubernetes版本: 1.16.9-aliyun.1
SpringCloud版本:Hoxton.SR1
# 描述
1)在通 Kubernetes 上运行SpringCloud(简写 S.C)服务时候,能正常请求。
2)Vue请求S.C接口出现跨域问题。 比如 vue.baidu.com 请求 java.baidu.com
# 排错步骤
## 一、Kubernetes Ingress 开启跨域
> 具体参考官方:https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#enable-cors
在 vue.baidu.com 与 java.baidu.com 的yaml配置
```json
metadata:
annotations:
nginx.ingress.kubernetes.io/cors-allow-headers: >-
DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization
nginx.ingress.kubernetes.io/cors-allow-methods: 'PUT, GET, POST, OPTIONS'
nginx.ingress.kubernetes.io/cors-allow-origin: '*'
nginx.ingress.kubernetes.io/enable-cors: 'true'
nginx.ingress.kubernetes.io/service-weight: ''
```
发现依然不行。
## 二、构建Vue镜像时候的Nginx配置
```json
server {
listen 80;
listen [::]:80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location / {
# CORS
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, PUT, POST, DELETE, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
if ($request_method = 'OPTIONS') {
return 204;
}
# rewrite .* /index.html break;
try_files $uri $uri/ /index.html;
root /usr/share/nginx/html;
index index.html index.htm;
}
location /static {
alias /usr/share/nginx/html/static;
index index.html;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
```
依然不行
## 三、代码
### S.C 网关配置
> 备注: 如果需要考虑额外安全问题:addAllowedOrigin 指定域名
还可以使用yaml配置方式,就不用下面的配置方式。
1、自定义跨域配置
```json
package com.test.gateway.config.Cors;
import com.test.gateway.filter.CorsResponseHeaderFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
@Configuration
public class CustomCorsConfiguration {
@Bean
public CorsResponseHeaderFilter corsResponseHeaderFilter() {
return new CorsResponseHeaderFilter();
}
@Bean
public CorsWebFilter corsWebFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration .addAllowedHeader("*");
corsConfiguration .addAllowedMethod("*");
corsConfiguration .addAllowedOrigin("*");
corsConfiguration .setAllowCredentials(true);
corsConfiguration .setMaxAge(600L);
source.registerCorsConfiguration("/**", corsConfiguration );
return new CorsWebFilter(source);
}
}
```
2、跨域请求头过滤
```json
package com.test.gateway.filter;
import com.google.common.net.HttpHeaders;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.NettyWriteResponseFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.ArrayList;
@Slf4j
public class CorsResponseHeaderFilter implements GlobalFilter, Ordered {
@Override
public int getOrder() {
return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER + 1;
}
@Override
@SuppressWarnings("serial")
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return chain.filter(exchange).then(Mono.defer(() -> {
exchange.getResponse().getHeaders().entrySet().stream()
.filter(kv -> (kv.getValue() != null && kv.getValue().size() > 1))
.filter(kv -> (kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)
|| kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS)))
.forEach(kv ->
{
kv.setValue(new ArrayList<String>() {{
add(kv.getValue().get(0));
}});
});
return chain.filter(exchange);
}));
}
}
```
## 四、END
> 结合二、三 解决跨域问题
Kubernetes, SpringCloud, Vue出现跨域排查与解决方法