双重跨域问题处理

本文介绍了在使用Spring Cloud Gateway或Zuul作为微服务网关时遇到的双重跨域问题,分析了问题原因,包括Nginx、Zuul和Gateway的配置冲突,并提供了详细的解决方案,包括在Gateway和Zuul中配置全局跨域,以及在Nginx中删除多余配置。同时,还提供了一个项目代码级别的拦截器设置示例。
摘要由CSDN通过智能技术生成

目录

双重跨域问题处理


1、问题出现的业务场景

所在微服务系统引入网关服务,通过网关服务调用原微服务系统,调用异常

前端异常信息如下:

The 'Access-Control-Allow-Origin' header contains multiple values 'http://localhost:8080,http://localhost:8080 *', but only one is allowed.

该属性只允许被设置为一个,但是目前有多个

2、问题原因

2.1、nginx设置了Access-Control-Allow-Origin,可能会导致该问题

 

2.2、zuul网关和被调用的服务都设置了跨域的配置,针对Access-Control-Allow-Origin有对应的设置,会导致双重跨域

在这里插入图片描述

2.3、gateway网关和被调用的服务设置了跨域配置,针对Access-Control-Allow-Origin有对应的设置,会导致双重跨域

 

3、处理方案

1、合理配置跨域 删除多余配置即可

2、网关层做相关配置

gateway的处理

spring:
  main:
    allow-bean-definition-overriding: true
    gateway:
      discovery:  #是否与服务发现组件进行结合,通过 serviceId(必须设置成大写) 转发到具体的服务实例。默认为false,设为true便开启通过服务中心的自动根据 serviceId 创建路由的功能。
        locator:  #路由访问方式:http://Gateway_HOST:Gateway_PORT/大写的serviceId/**,其中微服务应用名默认大写访问,配置lowerCaseServiceId可用小写。
          enabled: true
          lowerCaseServiceId: true
      #解决跨域问题
      globalcors:
        corsConfigurations:
          '[/**]':
            # 允许携带认证信息
            allow-credentials: true
            # 允许跨域的源(网站域名/ip),设置*为全部
            allowedOrigins: "*"
            # 允许跨域的method, 默认为GET和OPTIONS,设置*为全部
            allowedMethods: "*"
            # 允许跨域请求里的head字段,设置*为全部
            allowedHeaders: "*"
      #解决双重跨域 RETAIN_FIRST RETAIN_LAST RETAIN_UNIQUE
      default-filters:
        - DedupeResponseHeader=Access-Control-Allow-Origin Access-Control-Allow-Credentials Vary, RETAIN_UNIQUE
————————————————
版权声明:本文为CSDN博主「chenshiying007」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_27384769/article/details/108375731

zuul的处理

在这里插入图片描述

3、nginx配置

去掉nginx多余配置

add_header 'Access-Control-Allow-Origin' '*';

4、项目代码拦截器的设置

package gentle.filter;
 
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
 
/**
 * 解决跨域设置
 * (可把此设置放在 nginx 中,但只能设置一处)
 *
 * @author silence
 * @date 2018/12/11 15:19
 */
 
@WebFilter(filterName = "requestFilter", urlPatterns = {"/*"})
public class RequestFilter implements Filter {
 
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
 
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
 
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        HttpServletRequest request = (HttpServletRequest) servletRequest;
 
        // 此处 setHeader、addHeader 方法都可用。但 addHeader时写多个会报错:“...,but only one is allowed”
        // response.setHeader("Access-Control-Allow-Origin", "*");
        response.addHeader("Access-Control-Allow-Origin", request.getHeader("origin"));
        // 解决预请求(发送2次请求)
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with,Cache-Control,Pragma,Content-Type,Token, Content-Type");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        String method = request.getMethod();
        if (method.equalsIgnoreCase("OPTIONS")) {
            servletResponse.getOutputStream().write("Success".getBytes("utf-8"));
        } else {
            filterChain.doFilter(servletRequest, servletResponse);
        }
    }
 
    @Override
    public void destroy() {
 
    }
 
}

 

 

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值