通过自定义代理后端绕过 CORS
作为前端开发人员,你迟早会遇到 CORS 错误,如下所示:
to XMLHttpRequest at 'https://...' from origin 'https://...' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
CORS 简介
简而言之,跨域资源共享 (CSR)是一种安全机制,它允许 Web 浏览器在浏览domain1.com时访问 domain2.com 的数据。它还可以用于限制仅访问预定义的域。基本上,它要求后端和前端位于同一台服务器上,或者专门设置允许访问后端的来源。
CORS 默认是禁用的,如果您有权访问服务器端代码,则可以通过一些方法启用它。如果您参与了学校小组项目,并且有后端开发人员,请务必提醒他/她启用 CORS,否则您可能会被模拟数据困住(经验之谈)。
灵感
我第一次在浏览器控制台中遇到红色的 CORS 错误是在一个周六晚上,当时我在一个大学项目中尝试连接到我们的 Java Spring 后端,却无法正常工作,尽管 Postman 可以正常工作。由于 Java(尤其是 Spring)对我来说几乎像古希腊人一样(现在也是如此),所以我想尝试一种方法来绕过这个错误。由于 CORS 是在浏览器层面进行的,于是我就萌生了一个想法:为什么不构建一个更简单的 JS 后端,它执行相同的 API 请求,但启用 CORS,这样我就可以连接到它,而不是原来的 Java 后端。
Express 后端
Express.js是我遇到的第一个 Node.js Web 框架,非常适合这项任务。我们将创建一个最小的 Node/Express 后端应用程序,使用axios作为 http 库,并使用cors包在我们的服务器上启用 CORS(否则,这整个过程就毫无意义了)。
项目设置和包安装
为我们的项目创建一个文件夹后,打开终端并导航到该文件夹。我们使用以下命令初始化最基本的 package.json 文件:
npm init -y
完成后,我们安装所需的软件包:
npm i express cors axios
在开始编写代码之前,我们需要一个将要运行的文件。常用名称是server.js
或app.js
。由于本项目将所有代码放在一个文件中(并非最佳实践,但出于演示目的),我们可以直接使用index.js
。创建该文件并修改 package.json 文件,使 scripts 键如下所示:
"scripts": {
"start": "node index"
},
编码时间
终于到了写代码的时间了!打开index.js
(或者随便你在上一步里叫什么),这样我们就可以创建服务器了。我会把所有需要的代码以及(几乎)每一行的注释都复制到这里。
// packages import
const express = require("express");
const app = express();
const cors = require("cors");
const axios = require("axios");
// enable CORS
app.use(cors());
// set the port on which our app wil run
// important to read from environment variable if deploying
const port = process.env.PORT || 5000;
// basic string route to prevent Glitch error
app.get("/", (req, res) => {
res.send("Hello World!");
});
// the route we're working with
app.get("/users", (req, res) => {
// replace with a custom URL as required
const backendUrl = "https://jsonplaceholder.typicode.com/users";
// return the data without modification
axios.get(backendUrl).then(response => res.send(response.data));
});
// console text when app is running
app.listen(port, () => {
console.log(`Server listening at http://localhost:${port}`);
});
就是这样!您可以使用上面的代码并将其上传到Glitch等平台,以便在部署前端应用程序时托管和访问它。这就是为什么我们需要从环境变量中读取 PORT(如果可用)并设置一个根路由以返回一个简单的字符串,否则 Glitch 会认为应用程序有错误,因为没有返回任何内容。
该"/users"
路由包含我们需要连接到未启用 CORS 访问的后端的主要代码,并返回相同的未修改的数据。
额外奖励:数据修改
虽然您可以按原样返回数据,但您可以修改原始响应以使其更适应前端应用的需求。如果需要大量数据和修改,这可以提高前端应用在低端设备和较慢连接上的性能,因为这样可以减少收到的噪声数据,并且客户端需要进行的修改也更少。
修改它的代码片段非常简单(假设响应具有与上面相同的数据结构):
axios.get(backendUrl).then(response => {
const lastEpisodes = response.data.data.lastAvailableEpisodes;
const shows = lastEpisodes.map(episode => ({
id: episode.contentItemId,
title: episode.caption,
audioFile: episode.audio.metadata[0].path
}));
res.send(shows);
});
我相信您会同意第二种回应更加清晰且更容易理解。
结论
这是一个非常基础的示例,它使用自定义的、最基本的后端作为代理,绕过通常可以访问的受 CORS 限制的内容。它遵循所谓的“快乐路径”,这意味着没有错误处理,但这会偏离主题。从创建项目、修改响应到部署到 Glitch,整个过程只需不到 10 分钟,这比等待你的后端开发同事第二天早上醒来灵感消失要快得多。
文章来源:https://dev.to/bornfightcompany/bypassing-cors-via-custom-proxy-backend-2po