当前位置: 首页 > 知识库问答 >
问题:

如何使用Zuul中的CORS作为API网关AngularJS微服务

马冯浩
2023-03-14

我有一个使用ZuulNetflix作为API网关的应用程序,架构如下:

该架构运行良好,使用浏览器和邮递员我可以从微服务(服务1、2和3)访问不同的RESTendpoint。但是当我试图在我的前端Web应用程序(AngularJS WebApp)中使用它时,它在chrome控制台中给我带来了以下错误。

XMLHttpRequest cannot load http://localhost:8080/person/api/all. Response for preflight is invalid (redirect)

如果我设置@CrossOrigin注释,则通过自己的地址和端口使用服务将有效。但是当通过网关访问它时,restendpoint上没有@CrossOrigin注释将不起作用。

尝试在我的安全配置中创建以下筛选器,但仍然不起作用,而是在chrome控制台中出现以下错误。

@Bean
    public CorsFilter corsFilter() {
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        final CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("OPTIONS");
        config.addAllowedMethod("HEAD");
        config.addAllowedMethod("GET");
        config.addAllowedMethod("PUT");
        config.addAllowedMethod("POST");
        config.addAllowedMethod("DELETE");
        config.addAllowedMethod("PATCH");
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }

浏览器控制台(Chrome)。。。

XMLHttpRequest cannot load http://localhost:8080/person/api/all. Redirect from 'http://localhost:80/person/api/all' to 'http://localhost:80' has been blocked by CORS policy: Request requires preflight, which is disallowed to follow cross-origin redirect.

下面是AngularJS HTTP请求示例。

app.controller('loginCtrl', [
    '$scope', '$http', function($scope, $http) {

      $http.get('http://localhost:8080/person/api/all').then(function(data) {
        return console.log(data.data);
      });
]); 

有人知道如何处理它吗?到处都有很多教程,但他们的webapp也是一个Spring启动应用程序,要么位于api网关中,要么与@EnableZuulProxy注释分开,这不是我想要的。

如果有人能帮忙,先谢了。

共有3个答案

刘浩思
2023-03-14

你能尝试如下代码。它工作正常。

package com.gatway.configuration;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Component
public class CROSFilter implements Filter {

    private final Logger logger = LoggerFactory.getLogger(CROSFilter.class);

    public CROSFilter() {
        logger.info("CROSFilter init");
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
        throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;

        response.setHeader("Access-Control-Allow-Origin", request.getHeader("origin"));
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, HEAD, PATCH, PUT");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me");

        chain.doFilter(req, res);
    }

    @Override
    public void init(FilterConfig filterConfig) {
    }

    @Override
    public void destroy() {
    }

}
樊宏义
2023-03-14

我尝试了以下2种解决方案,只是为了看看CORS标头(“访问控制-允许-*”)是否被添加到服务器响应中,仅供参考:

测试1:配置Spring安全性

配置spring web mvc配置器:
https://spring.io/blog/2015/06/08/cors-support-in-spring-framework
并在Spring Security级别启用CORS:
https://docs.spring.io/spring-security/site/docs/current/reference/html/web-app-security.html#cors

结果:从http响应中看不到cors头

测试 2:将筛选器添加到:在返回响应时添加 cors 标头 https://stackoverflow.com/a/47485985/2893542

结果:从超文本传输协议响应中看到cors标头

姜锋
2023-03-14

使用类似的架构,面对类似的问题,我做了以下更改并为我工作:

config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("OPTIONS");
config.addAllowedMethod("HEAD");
config.addAllowedMethod("GET");
config.addAllowedMethod("PUT");
config.addAllowedMethod("POST");
config.addAllowedMethod("DELETE");
config.addAllowedMethod("PATCH");
source.registerCorsConfiguration("/**", config);

config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("*", config);

在我的angular http请求中,我添加了头,

{'Access-Control-Allow-Origin':'*'}

为我工作。

我试图在最初的情况下,我只能访问在Zuul路由映射中映射的第一个URL。但是在将/**替换为*之后,可以毫无问题地访问所有映射,Angular方面也是如此,所有请求都应该包括标头。我也是这个问题的新手,可能稍后会有更多的信息和细节,现在我可以说它对我有用,希望它也对你有用。

 类似资料:
  • 我有两个微服务,用户微服务和订单微服务。 因此客户端只需要调用一个endpointhttp://localhost:9090/api/getdetail 我们如何在API网关级别实现这一点?

  • 我跟踪了服务,当它们部署在localhost中(通过eclipse)时,它们工作得很好。但在部署为单独的docker容器时无法调用rest服务。 我是一个新的docker并且参加了教程来了解这是如何工作的。 祖尔阿皮门路 用户服务 尤里卡注册服务信息 注意:“DE4396A354EA”是“用户服务”的容器id 请提供关于如何解决此问题的指导,并提供任何链接,我可以在这些链接中获得关于在docker

  • 本文向大家介绍浅谈Spring Cloud中的API网关服务Zuul,包括了浅谈Spring Cloud中的API网关服务Zuul的使用技巧和注意事项,需要的朋友参考一下 到目前为止,我们Spring Cloud中的内容已经介绍了很多了,Ribbon、Hystrix、Feign这些知识点大家都耳熟能详了,我们在前文也提到过微服务就是把一个大的项目拆分成很多小的独立模块,然后通过服务治理让这些独立的

  • 对于微服务,常用的设计模式是API-Gateway。我对它的实现和含义有点困惑。我的问题/顾虑如下: 为什么没有普遍讨论微服务的其他模式?如果是,那么我错过了吗? 如果我们部署网关服务器,不是瓶颈吗? 网关服务器是否容易因单点请求过多而崩溃/失败?我相信此时负载会很大(请记住Netflix正在做这样的事情)。如果我理解错误,请纠正我。 流/下载/上传数据(如文件、视频、图像)也将与其他中间件服务一

  • 背景 我想实现本文中提出的设计。 客户端首先使用IDP(OpenID Connect/oauth2)进行身份验证 IDP返回一个访问令牌(不透明的令牌,没有用户信息) 客户端使用授权头中的访问令牌通过API网关进行调用 API网关使用访问令牌向IDP发出请求 IDP验证访问令牌是否有效,并以JSON格式返回用户信息 API网关将用户信息存储在JWT中,并使用私钥对其进行签名。然后将JWT传递给下游

  • 当我们部署到pcf时,Netflix eureka、zuul、ribbon、feign spring cloud配置不有用?(如果是,在pcf中有哪些可选方案以及如何配置它们?) 由于构建微服务遵循CI/CD方法,开发人员在推送代码之前如何验证其微服务的工作,因为我们在生产PCF中没有使用eureka、zuul、ribbon、feign。(如何在developer Machine中模拟pcf环境?