Node.js 中 CORS 的使用2025年2月25日 | 10分钟阅读 在 Node.js 中,CORS 代表跨域资源共享(Cross-Origin Resource Sharing)。前端客户端可以使用 JavaScript 方法从外部后端服务器请求资源。同源策略禁止跨域请求,而需要使用 CORS 头部来禁用此功能。本文将教我们如何配置一个 ExpressJS 后端服务器,并使用一个前端向其提交跨域请求。 先决条件
什么是 CORS?CORS 的缩写是跨域资源共享(Cross-Origin Resource Sharing)。每个 Web 应用程序都有一个前端和一个后端,它们都使用 API 进行相互通信。前端和后端通常托管在同一个源上。Node.js 的 CORS 有助于从外部服务检索资源。下面的类比可以帮助解释这一点。 以一个餐厅应用为例。源就是我们餐厅的地址。用餐区是前端,厨房是后端。厨房和用餐区位于同一地址。因此,它们可以交换食物和服务,或者在我们的例子中是资源。顾客可能会感到不适并需要药物,而这些药物需要从餐厅外的其他地方带来。从技术上讲,前端请求的后端不是它自己的源。因此,跨域资源共享是前端从一个独立的后端请求额外服务或资源的过程。 通常,应用程序的前端只能使用其自己的源向后端进行 API 调用。从安全角度来看,这被称为同源策略,它非常重要。浏览器将拒绝来自或去往不同源前端的任何请求。当出现需要访问第三方资源的情况时,CORS 使我们能够绕过这一策略。 ![]() 注意:浏览器可以在同源策略下发出请求,但响应将被禁止。CORS 是如何工作的?正如我们所讨论的,浏览器实施了同源策略,允许从其自己的 URL 访问资源,但阻止从外部 URL 检索资源。Node.js 中的 CORS 可以改变这一点。浏览器发送的请求消息中可能包含一个 Origin 头部。如果请求发送到同源服务器,浏览器会接受该请求并且不会被阻止。另一方面,如果请求发送到非源服务器,则该请求被称为跨域请求。服务器在发送响应时,会在响应中包含 Access-Control-Allow-Origin 头部。此头部的值必须与请求的 Origin 头部的值一致。如果匹配,则请求被批准。如果它们不匹配,浏览器将阻止响应数据。此时,用户的浏览器控制台中将出现臭名昭著的 CORS 错误。 在进一步深入之前,让我们先探讨一下 Node.js 中 Cors 的源(Origin)。正如我们之前提到的,源的改变将阻止所有请求,直到 CORS 被实现。 源是一个请求头部,它标识了发出请求的客户端的 URL。它分为三个部分:
这三者结合的结果如下: ![]() 对上述三个组件的任何更改都可能导致 cors 错误和新的源 URL。为了防止资源被阻止,我们必须确保请求和响应的源匹配,或者在 Node.js 中配置了 CORS。 现在让我们来看看头部(headers)。简单来说,头部用于随请求或响应传递额外的数据。浏览器或服务器需要这些数据来执行多项任务。请求头提供了有关请求的附加细节,而响应头则提供了有关响应的附加细节。
示例让我们看一个 YouTube 克隆应用的例子,来更多地了解 Node.js 中的 cors。
![]() 在 Node.JS 中的一个基本 CORS 演示(错误与解决方案示例)当 CORS 启用时,已经可以观察到跨域资源获取成功工作。现在,让我们看看当在未启用 CORS 的情况下发出跨域请求时会发生什么。我们将创建一个简单的 application.js 来演示 node 中的 cors。 步骤 1首先,请确认我们的计算机上已安装 npm 和 node.js。启动终端并输入以下命令以检查其是否工作: 如果尚未安装,请访问 Node.JS 网站下载并安装该库。 步骤 2在这一步,我们将组织我们的项目。该命令为我们创建了一个新目录。 我们使用该命令进入这个新目录。 我们使用该命令初始化了一个新的 NPM 项目。 我们可以在终端中输入所需的值。 ![]() 现在,为了创建我们的服务器,我们将使用 npm 安装 ExpressJS。我们执行以下命令: 安装一个 IDE 扩展将使我们能够在服务器上运行我们的 HTML 页面。一个 IDE 插件可以模拟在服务器上托管前端客户端。我们的 IDE 是 VSCode,我们将使用的插件是 Live Server。 步骤 3现在,让我们来编写服务器代码。我们的服务器将使用 ExpressJS 包创建,应用程序将监听一些端口。我们将建立路径 '/data',一个 "GET" 请求将返回 JSON 数据。这部分代码如下: 步骤 4现在,让我们开始编写前端页面。一个简单的 HTML 页面使用 JavaScript 脚本向我们的后端服务器发起一个 fetch 请求。这部分代码如下: 我们的文件夹结构如下所示: ![]() 步骤 5
在我们的例子中,它将是: 这将启动我们的后端服务器。 ![]() 现在,导航到前端的 HTML 页面,然后右键单击并选择“使用 Live Server 打开”。 ![]() 步骤 6现在,在浏览器中转到 HTML 页面来打开控制台。右键单击浏览器窗口选择“检查”。接下来,移动到“控制台”面板。这里将看到 CORS 错误。 ![]() 正如错误消息中所述,由于前端和后端的源不同,浏览器拒绝了该请求。之后,浏览器显示了 CORS 错误。 现在,我们将使用 CORS 来解决这个问题。我们将使用 NPM 的 CORS 包。可以使用以下命令在 node.js 中安装 cors: 步骤 7在这一步,我们在服务器上使用一个中间件,该中间件使用客户端的源 URL。我们创建一个对象并将其通过中间件传递,使用 origin 作为键,URL 作为值。这部分代码如下: 在这里,我们可以观察到中间件包含了客户端的源 URL。之前的错误消息中也有这个 URL。现在,我们将尝试重新启动我们的前端和后端服务器。根据控制台的检查,我们最终得到了想要的数据。因此,我们已经在 node.js 中使用 cors 成功下载了跨域资源。 ![]() 启用所有 CORS 请求在上一节中,我们为特定的源使用了 cors 中间件。这只会允许来自该特定 URL 的不同源之间的资源共享。如果我们想在 node.js 中允许所有 CORS 请求,我们可以将我们的中间件更改为以下内容: 这条语句必须写在我们的路由之前。 为单个路由启用 CORS在上面的方法中,使用 app.use() 为所有路由启用了中间件。如果我们想在 node.js 中对特定路由使用 CORS,我们可以将我们的路由更改为如下所示: 正如我们在上一节中看到的,我们只为两个路由中的一个添加了 cors。 正如我们所见,在上面的代码片段中,我们只为两个路由中的一个添加了 cors。 使用选项配置 CORS 正如我们之前所见,cors() 函数接受一个带有 origin 的对象。这个对象也可以显式声明除 origin 之外的其他属性。举个例子,考虑这个: 在这里,请求方法和源 URL 都已提供。只有上述方法会被批准。在这种情况下,如果客户端提交一个 patch 或 delete 请求,它将会失败。他们将被允许发出 put 或 get 请求。 使用函数配置动态 CORS 源另一个选择是尝试动态源配置。根据我们的需要,可以采取多种方法来实现这一点。在下面的部分中,我们构建了一个从数据库异步获取源 URL 的例子。 在这种情况下,我们根据请求头从数据库中检索我们的源。之后,options 对象将此源分配给我们的 Origin。 从数据源加载允许的源列表服务器也可以为我们提供允许的源列表。其代码片段如下: 这将加载数据库中允许的源(db 对象)。如果没有找到源或者访问被拒绝,则会显示一个错误。 预检请求每个请求都必须存在一些必需的特性,例如内容类型或请求方法。这些细节有时在请求头中是缺失的。在这些情况下,浏览器会利用其可用的信息,通过一个预检请求向后端服务器询问它是否会完成这些请求。可以将这个预检请求看作是一个测试,以确定我们是否会收到对后续请求的响应。虽然这最初看起来像是一种低效的方法,但这个响应可以在预定的时间内被缓存。我们可以使用这个示例来使用一个预检请求: 结论
下一个主题Node.js 中解复用器的用途 |
我们请求您订阅我们的新闻通讯以获取最新更新。