问题发现
正常情况下,跨域是这样的: 

  1. 微服务配置跨域 + zuul 不配置 = 有跨域问题 
  2. 微服务配置 + zuul 配置 = 有跨域问题 
  3. 微服务不配置 + zuul 不配置 = 有跨域问题 
  4. 微服务不配置 + zuul 配置 = ok

然而云环境中每个服务自己有跨域解决方案,而网关需要做最外层的跨域解决方案. 如果服务已有跨域配置网关也有,会出现 * 多次配置问题。

Access-Control-Allow-Origin:”*,*”

也就是 multiple Access-Control-Allow-Origin
!!!所以我们就要,微服务配置 + zuul 配置 = 解决跨域问题

zuul 的跨域忽略配置
使用 ZUUL 配置忽略头部信息   解决 cookie 跨域携带问题

zuul:
需要忽略的头部信息,不在传播到其他服务
  sensitive-headers: Access-Control-Allow-Origin
  ignored-headers: Access-Control-Allow-Origin,H-APP-Id,Token,APPToken

微服务应用的跨域配置

 
import javax.servlet.*;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
import java.io.IOException;  
@Component    
public class CorsFilter implements Filter {    
    @Override  
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {    
        HttpServletRequest request = (HttpServletRequest) req;  
        HttpServletResponse response = (HttpServletResponse) res;    
       /* String curOrigin = request.getHeader("Origin");  
        System.out.println("### 跨域过滤器 -> 当前访问来源 ->"+curOrigin+"###");   */  
        response.setHeader("Access-Control-Allow-Origin", "*");    
        response.setHeader("Access-Control-Allow-Methods", "*");    
        response.setHeader("Access-Control-Max-Age", "3600");    
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with");   
        chain.doFilter(req, res);    
    }    
    @Override  
    public void init(FilterConfig filterConfig) {}  
 
    @Override  
    public void destroy() {}    
}    
 
 

zuul 路由的跨域配置
@EnableZuulProxy
 启动类里增加 bean

 
import org.springframework.boot.SpringApplication;  
import org.springframework.boot.autoconfigure.SpringBootApplication;  
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;  
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;  
import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Primary;  
import org.springframework.stereotype.Component;  
import org.springframework.web.cors.CorsConfiguration;  
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;  
import org.springframework.web.filter.CorsFilter;  
  
import java.util.ArrayList;  
import java.util.List;  
@Bean  
public CorsFilter corsFilter() {  
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();  
final CorsConfiguration config = new CorsConfiguration();  
config.setAllowCredentials(true); // 允许 cookies 跨域  
config.addAllowedOrigin("*");// 允许向该服务器提交请求的 URI,* 表示全部允许。。这里尽量限制来源域,比如 http://xxxx:8080 , 以降低安全风险。。  
config.addAllowedHeader("*");// 允许访问的头信息,* 表示全部  
config.setMaxAge(18000L);// 预检请求的缓存时间(秒),即在这个时间段里,对于相同的跨域请求不会再预检了  
config.addAllowedMethod("*");// 允许提交请求的方法,* 表示全部允许,也可以单独设置 GET、PUT 等  
config.addAllowedMethod("HEAD");  
config.addAllowedMethod("GET");// 允许 Get 的请求方法  
config.addAllowedMethod("PUT");  
config.addAllowedMethod("POST");  
config.addAllowedMethod("DELETE");  
config.addAllowedMethod("PATCH");  
source.registerCorsConfiguration("/**", config);  
return new CorsFilter(source);  
}