8

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

在此处输入图像描述

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

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

如果我设置@CrossOrigin注释,通过它自己的地址和端口使用服务将起作用。但是当通过网关访问它并且@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 Boot 应用程序,要么位于 api 网关中,要么与 @EnableZuulProxy 注释分开,这不是我想要的。

如果有人可以提供帮助,请提前致谢。

4

4 回答 4

1

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

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);

在我的角度 http 请求中,我添加了标题,

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

为我工作。

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

于 2017-07-18T09:19:01.600 回答
0

如果要部署到 Azure 应用服务,可以在左侧菜单中检查 CORS 配置。

于 2021-05-20T03:14:19.920 回答
0

你可以试试下面的代码。它工作正常。

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() {
    }

}
于 2020-11-28T04:03:47.017 回答
0

我尝试了以下 2 个解决方案,只是为了查看是否将 CORS 标头(“Access-Control-Allow-*”)添加到服务器响应中,仅供参考:

测试1:配置spring security

配置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

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

于 2019-01-16T23:12:04.003 回答