在运行本地 API 实例的 Angular 应用程序中解决“被 CORS 策略阻止”错误

Posted

技术标签:

【中文标题】在运行本地 API 实例的 Angular 应用程序中解决“被 CORS 策略阻止”错误【英文标题】:Getting Around "blocked by CORS policy" Error in Angular App Running Local Instance of API 【发布时间】:2019-10-02 15:15:42 【问题描述】:

我正在针对我们基于 Node/Express/MongoDB 的 API 的本地实例(我在 http://localhost:3000 运行)测试我们的 Angular 应用程序(在 http://localhost:4200 运行)。

我正在测试的端点之一用于允许我们的内部用户下载文件。现在,在我们实际的 API URL 上,我们设置了 CORS 策略(详见下文)——这是一个在 *** 后面运行的内部办公应用程序。

但是,当我尝试在针对 API 的本地实例运行的本地应用上测试此下载功能时,我收到以下错误消息:

访问 XMLHttpRequest 在 'http://localhost:3000/v0/filegenerator/download?emailDocId=47dh385686e780c18e905&apikey=9d98e41d-44e9-4bbb-ab3d-35b7df5272dc&token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJDUkVXTWVtYmVyIjoiNWmNoIjoiU2MDc0ODd9.bA5B5bx4wPSSiVCS_LxTK1gifjtif8dj29sfUBHqpOg' 来自原点“http://localhost:4200”已被 CORS 策略阻止: 对预检请求的响应未通过访问控制检查:它 没有 HTTP ok 状态。

这里有几个问题:

1.) 这是一般的 Chrome 安全错误消息吗?

2.) 有没有办法可以关闭它,以便测试下载文件?或者我只能通过点击我们实际的实时 API 来测试它吗?

如何在我的测试环境中最好地解决这个问题?

添加说明:我确实有一个 CORS 扩展 - “Allow-Control-Allow-Origin: * 1.0.3” - 安装在 Chrome 中,当前设置为“启用跨域资源共享”。

此外,在我们的后端 Node/Express 环境中,这是我们当前的设置:

  app.use(function(req, res, next) 
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    res.header("Access-Control-Allow-Methods", "PUT, POST, GET, DELETE, OPTIONS");
    return next();
  );

【问题讨论】:

简单的方法是,你有一个用于 cors 的 chrome 扩展,所以你可以测试它,但你应该更好地处理这个,扩展只是一个快速修复 说“你应该更好地处理这个”是没有帮助的,因为它太模糊了。如果您要发表评论,请提供更多详细信息。另外,我已经在 Chrome 中有一个 CORS 扩展,它设置为“启用跨域资源共享”。 我不知道你应该做什么,但你应该在后端的某个地方处理它,我只是说你可以使用该扩展作为快速修复,直到你找到/有人提供修复后端。 已经有 CORS Chrome 扩展。而且我认为您无法“在后端”做任何事情来处理这个问题。我认为这是一个前端浏览器的问题。如果没有,我需要详细信息才能知道如何解决它。 我在 Mac 上,所以我关闭了 Chrome,打开我的终端并运行:open -a Google\ Chrome --args --disable-web-security --user-data-dir。似乎成功了。 【参考方案1】:

这是浏览器中的一般安全功能。您无法将其关闭。解决此问题的一种方法是通过设置 Access-Control-Allow-Origin 标头来允许您在服务器端使用源。但是,如果您不单独处理它们,这不适用于预检 (OPTIONS) 请求。

如果这是不可能的(由于 3rd 方库、服务、身份验证等),您可以在 Angular 中设置反向代理,它允许您通过隧道传输所有请求。对于浏览器来说,您的请求看起来与您的 Angular 应用程序发送到相同的域(和端口)(因此假设具有相同的来源)。

只需在您的项目中创建一个 proxy.conf.js,如下所示:

const path = "/proxy_path/*";
const proxy = "/proxy_path/";

const pathRewrite = ;
pathRewrite["^" + proxy.slice(0, -1)] = "";

const configs = 
    target: 'your_service_url',
    secure: false,
    changeOrigin: true,
    pathRewrite,
    logLevel: "debug"


const PROXY_CONFIG = ;
PROXY_CONFIG[path] = configs;

module.exports = PROXY_CONFIG;

并使用ng serve --host 0.0.0.0 --disable-host-check --proxy-config <PATH_TO_PROXY_CONF> 启动它。

我希望这会有所帮助!

【讨论】:

谢谢,但请看我上面添加的内容。我们的后端 API 目前确实设置了 Access-Control-Allow-Origin。 我明白了。预检请求 (OPTIONS) 将不受 Allow-Control-Allow-Origin 标头的影响。所以我看到的唯一选择是在 Angular 中设置代理。我将很快发布一个示例。 这是一个被低估的答案。在这种情况下,创建反向代理绝对是最好的长期解决方案。【参考方案2】:

CORS 标头基本上是服务器表示“我将这些其他服务器识别为向我发送请求的源,它对浏览器应该是安全的”的一种方式。如果不存在标头,则只有来自同一服务器的请求才被认为是安全的。

您应该能够配置您的本地应用程序以将标头添加到响应中。

纯文本标题看起来像 Access-Control-Allow-Origin: localhost:4200

【讨论】:

谢谢。一个这样的标题看起来像什么的实际示例会很有帮助。 好的,那纯文本标题会去哪里? @Muirik 你知道chrome.exe --disable-web-security 吗?您需要先关闭所有 chrome 浏览器进程,然后运行命令。 @Muirik 这是一个 HTTP 标头,如何将其添加到响应中通常高度依赖于您的 Node 服务器所使用的框架 我在 Mac 上,所以我关闭了 Chrome,打开终端并运行:open -a Google\ Chrome --args --disable-web-security --user-data-dir。似乎成功了。【参考方案3】:

出于测试目的,您可以使用 chrome 的 disable-web-security 标志。

关闭所有 chrome 窗口。 运行chrome.exe --disable-web-security

【讨论】:

这种方法对我有用。根据您使用的机器,它会有所不同。我在 Mac 上,所以我关闭了 Chrome,打开了终端并运行:open -a Google\ Chrome --args --disable-web-security --user-data-dir。为我工作。

以上是关于在运行本地 API 实例的 Angular 应用程序中解决“被 CORS 策略阻止”错误的主要内容,如果未能解决你的问题,请参考以下文章

Angular Service HttpClient API 在生产中请求 404,但不是在本地

Angular 6 调用 localhost API

带有亚马逊产品 API 的 Angular CORS

CORS 停止 Angular 应用程序和 .NET CORE 3.0 API 之间的通信

处理内存不足后返回的 Angular API 致命错误处理程序

Angular 应用程序和部署在 Docker 容器中的 Spring Boot API 之间的通信问题