在运行本地 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.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,但不是在本地
CORS 停止 Angular 应用程序和 .NET CORE 3.0 API 之间的通信