什么是代理,它在 Node.js 中是如何工作的?
原文作者:Victor Jonah
原文地址:blog.logrocket.com/proxy-serve…
翻译:一川
写在前面
在本文中,我们将深入研究代理服务器,包括它们是什么、它们的优点、可用的类型以及它们的潜在缺点。然后,我们将探索如何在Node
中使用Proxy.js
以掌握幕后发生的事情。
什么是代理服务器?
想象一下自己在一家餐馆里。你想点一瓶赤霞珠,但你不想去酒吧。相反,你打电话给服务员,给他们你的订单,他们去酒吧为你点一瓶葡萄酒。在这种情况下,您是计算机,服务员是代理服务器,吧台是互联网。
代理服务器充当中间人,在不向互联网提供您的信息的情况下传达您的需求和请求。代理还可以允许您绕过某些安全阻止,并允许您访问可能被阻止的信息。这是通过使用不泄露您的个人IP
地址的代理服务器来实现的。
每台与互联网通信的计算机都已经有一个互联网协议(IP
)地址。对于个人用户,IP
地址就像您计算机的住宅地址。就像服务员知道把你的葡萄酒带到哪张桌子一样,互联网知道将你请求的数据发送回你的IP地址。
另一方面,当代理服务器发送您的请求时,它能够将您的IP地址更改为自己的地址和“位置”,从而保护您的个人地址和数据。
那么为什么要使用代理服务器呢?您应该始终使用一个来保护您的 IP 吗?这是搜索数据的最安全方式吗?如何确保使用正确的服务器?这些都是重要的问题,我们将在以下部分中回答它们。
为什么要使用代理服务器?
个人或组织使用代理的原因有多种,其中最常见的是解锁其所在地区受限制的网站或在浏览时保持匿名。以下是可能使用代理服务器的一些情况:
- 访问受限制的 Web 内容:到目前为止,大多数组织已经开始使用代理服务器,但长期以来,员工可以使用代理在工作中使用代理访问被禁止的 Web 内容,例如音乐、视频或游戏网站。Web 用户还可以使用代理服务器绕过特定区域中被阻止的 Web 内容。例如,如果您因为出国旅行而无法通过流媒体服务观看电影,则使用代理服务器可以欺骗流媒体网站,使其相信您仍在自己的国家/地区
- 提供匿名性:使用代理可以保护网络冲浪者在浏览时不会泄露其身份。代理还可以防止用户的 Web 活动被跟踪,并确保其 IP 地址和个人信息的安全
- 提高安全性:除了匿名之外,代理服务器还提供额外的安全优势,包括加密的Web请求以及设置为Web过滤器或防火墙的能力
- 更快的性能:尽管代理服务器不与互联网共享个人信息,但它们仍然能够缓存经常访问的Web内容。在我们的葡萄酒示例中,服务员可能没有告诉调酒师你是谁,但下次你来餐厅时,他们会知道你更喜欢出租车。通过保留经常访问的资源的副本,代理服务器可以减少带宽使用,从而提高浏览速度
正向和反向代理类型
有两种主要类型的代理服务器:正向代理和反向代理。代理的功能方向不同:有些在客户端和服务器之间移动,而另一些则在服务器和客户端之间移动。我们将在下面更详细地讨论这个问题。
前向代理
转发代理(通常称为隧道或网关)是互联网上最常见且最易于访问的代理类型。转发代理是为组织或特定个人提供服务的开放代理,就像我们在上一节中介绍的用例一样。转发代理最常见的用途是存储和转发网页,它通过减少带宽使用来提高性能。
转发代理放置在互联网和客户端之间;如果代理归组织所有,则将其放置在内部网络中。许多组织使用转发代理来监视 Web
请求和响应、限制对某些Web
内容的访问、加密事务以及更改IP
地址以保持匿名。
反向代理
与正向代理不同,反向代理不是开放的。相反,它们在后端运行,并且通常由其内部网络中的组织使用。
反向代理接收来自客户端的每个请求,充当中间服务器,然后将这些请求转发到应处理该请求的实际服务器。然后,来自服务器的响应通过代理发送到客户端,就像它来自 Web
服务器本身一样。
反向代理体系结构有很多好处,但最常见的是负载平衡。由于反向代理位于互联网和Web
服务器之间,因此它能够将请求和流量分发到不同的服务器,并管理内容的缓存以限制服务器过载。
在内部网络中安装反向代理的其他原因包括:
- 压缩:通过压缩
Web
文件来增加加载时间 - 安全性:防止
DDoS
攻击。攻击不是到达实际服务器,而是攻击代理 - 外联网发布:通过防火墙管理对内容的访问
- 勺子喂食:缓存
Web
内容并限制多余的资源支出 - 加密:保护私人数据并管理
SSL
在Node.js中使用代理
现在我们了解了什么是代理以及它们的用途,我们准备探索如何在 Node.js
中使用代理。下面,我们将使用 npm
包制作一个简单的代理。(查看此 Github
存储库以获取完整代码。
我们将使用此 npm
包来演示如何将客户端 GET
请求代理到目标主机。首先,我们必须初始化我们的项目以生成我们的 package.json
和 index.js
文件:
npm init
接下来,我们将安装两个依赖项:
- expres:我们的迷你节点框架
- http-proxy-middleware:代理框架
npm install express http-proxy-middleware
在 index.js
文件(或要代理请求的任何文件)中,添加以下必需依赖项:
import { Router } from 'express';
import { createProxyMiddleware } from 'http-proxy-middleware'
最后,我们添加选项并定义我们的路由:
const router = Router();
const options = {
target: 'https://jsonplaceholder.typicode.com/users', // target host
changeOrigin: true, // needed for virtual hosted sites
pathRewrite: {
[`^/api/users/all`]: '',
}, // rewrites our endpoints to '' when forwarded to our target
}
router.get('/all', createProxyMiddleware(options));
通过使用pathRewrite
,我们能够将具有端点 api/users/all
的应用程序代理到名为jsonplaceholder
的 API。当我们的客户端从浏览器点击 api/users/all
时,他们将收到来自 https://jsonplaceholder.typicode.com/users
的用户列表,如下所示:
利用代理在Node.js中进行缓存
代理也可用于在Node.js
中进行缓存。让我们通过一个使用apicache
包的示例来了解如何执行此操作。
在下面添加代码片段:
import apicache from 'apicache';
let cache = apicache.middleware;
router.get('/all', cacheMiddleware(), createProxyMiddleware(options));
function cacheMiddleware() {
const cacheOptions = {
statusCodes: { include: [200] },
defaultDuration: 300000,
appendKey: (req:any, res: any) => req.method
} as any;
let cacheMiddleware = apicache.options(cacheOptions).middleware();
return cacheMiddleware;
}
这会将代理请求缓存五分钟,在此期间,完整代码变为:
import { Router } from 'express';
import apicache from 'apicache'
import {createProxyMiddleware} from 'http-proxy-middleware'
const router = Router();
// proxy middleware options
const options = {
target: 'https://jsonplaceholder.typicode.com/users', // target host
changeOrigin: true, // needed for virtual hosted sites
pathRewrite: {
[`^/api/users/all`]: '',
},
}
router.get('/all', cacheMiddleware(), createProxyMiddleware(options));
function cacheMiddleware() {
const cacheOptions = {
statusCodes: { include: [200] },
defaultDuration: 300000,
appendKey: (req:any, res: any) => req.method
} as any;
let cacheMiddleware = apicache.options(cacheOptions).middleware();
return cacheMiddleware;
}
export default router;
让我们通过在浏览器控制台中运行下面的测试脚本来测试这一点:
console.time('first fetch')
await fetch('http://localhost:3000/api/users/all')
console.timeEnd('first fetch')
console.time('second fetch')
await fetch('http://localhost:3000/api/users/all')
console.timeEnd('second fetch')
console.time('third fetch')
await fetch('http://localhost:3000/api/users/all')
console.timeEnd('third fetch')
结果如下:
如您所见,初始请求从外部服务器获取响应大约需要 764
秒 (https://jsonplaceholder.typicode.com/users
),但后续请求的请求时间较短,第二个请求为 482
秒,第三个请求为 13 秒,这是由于从服务器缓存获取响应而不是直接向 https://jsonplaceholder.typicode.com/users
端点发出请求。
在Node.js中使用代理进行负载平衡
代理也可用于 Node.js
中的负载平衡。让我们更新上一节中的示例,以启用目标之间的负载均衡。
添加下面的代码片段:
const targets = [
'https://jsonplaceholder.typicode.com/users',
'https://jsonplaceholder.typicode.com/posts'
]
const options = {
target: targets[(Math.floor(Math.random() * 2))], // target host
changeOrigin: true, // needed for virtual hosted sites
pathRewrite: {
[`^/api/users/all`]: '',
},
}
这会将两个目标服务器添加为代理的目标终结点。理想情况下,这些服务器将运行相同的应用程序代码。
此方法使用随机数在两个可用终结点之间对请求进行负载均衡。然后缓存结果,完整代码变为:
import { Router } from 'express';
import apicache from 'apicache';
import {createProxyMiddleware} from 'http-proxy-middleware';
const router = Router();
const targets = [
'https://jsonplaceholder.typicode.com/users',
'https://jsonplaceholder.typicode.com/posts'
]
const options = {
target: targets[(Math.floor(Math.random() * 2))], // target host
changeOrigin: true, // needed for virtual hosted sites
pathRewrite: {
[`^/api/users/all`]: '',
},
}
router.get('/all', cacheMiddleware(), createProxyMiddleware(options));
function cacheMiddleware() {
const cacheOptions = {
statusCodes: { include: [200] },
defaultDuration: 60000,
appendKey: (req:any, res: any) => req.method
} as any;
let cacheMiddleware = apicache.options(cacheOptions).middleware();
return cacheMiddleware;
}
export default router;
对于生产站点,最好使用更成熟的方法(如 Nginx)来处理请求,因为它会自动处理负载平衡。
使用代理的潜在风险
正如使用代理有好处一样,也存在一些风险和缺点:
- 免费代理不安全。它们通常由黑客创建以窃取数据
- 廉价代理可能无法完全加密您的请求,从而使您的某些数据不安全
- 如果您严重依赖代理,您的 Web 请求可能会变慢
- 缓存的Web内容仍然可以存储您的密码和安全数据,这意味着代理服务提供商可以查看私人信息
话虽如此,这些风险的解决方案很简单:找到一个可靠且受信任的代理服务器。
写在最后
在本文中,我们了解到代理服务器就像我们 Web 请求的中间人,为我们在 Web
上的事务提供了更高的安全性。在我们的 Node.js
示例中,我们能够从 JSONPlaceholder
代理我们的端点,并重写我们的URL
以保持我们的身份从 API
中屏蔽。
虽然正向和反向代理可能具有不同的功能,但总体而言,代理服务器可以降低安全风险、提高匿名性,甚至提高浏览速度。
一川说
觉得文章不错的读者,不妨点个关注,收藏起来上班摸鱼的时候品尝。
欢迎关注笔者公众号「宇宙一码平川」,助你技术路上一码平川。