代理
最近在学习nginx,其中一个最重要的概念就是反向代理,但是反向代理究竟是什么?
反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。
这是百度百科上给出的标准答案,但是光看定义根本完全不懂啊!所以我们先来明白,代理是怎么样的一个概念。
代理 (proxy)在百科上的释义: 代理也称代理服务器(Proxy Server),主要工作在会话层。指以代理服务器的方式来接收internet上的连接请求,然后将请求转发给内部网络上的服务器。
总而言之,它就是一个委托人的作用。
正向代理
代理也分两种,正向代理和反向代理,这里先介绍正向代理。
正向代理是一般常见的代理方式,客户机访问不到原始服务器的情况下,转而将请求发送给正向代理服务器,正向代理服务器将资源从原始服务器中取回来,在发送给客户机。正向代理的一般用途就是为在防火墙内的客户机提供访问internet的途径。
反向代理
客户机像反向代理服务器发送请求,反向代理服务器判断要把请求发送给哪个原始服务器。这里与正向代理不同的是,反向代理服务器客户机是不用进行设置的。所以一般也用在网站的负载均衡上。
反向代理的实践
这里先不讲nginx的反向代理的实现,有机会再另起一篇文章……这里来实现一个反向代理服务器。
- 需求
网站上的public/image/目录下有图片资源,用户在敲入/images/xxxxx的时候会访问图片,这时候我们想先让请求跳转到cdn服务器上(现在的web框架下一般会把图片资源都放在一个专门的cdn服务器上来使用户高速访问),如果cdn服务器上没有该图片资源,则在/public/images/下查找。 - 解决方案
这种需求很符合代理类型中的反向代理,用户发送请求给代理,代理判断该请求是该发往cdn服务器去取资源,还是在本服务器取资源。而正向代理需要用户自己设置去哪里取资源….好蠢。 - 技术选型
NodeJs
第一步:使用express框架先搭建一个简单的服务器
index.js,这个文件就是启动服务器的主文件,撸代码之前你得确定你已经稳定安装了node环境……
我们先来梳理下整个小项目的目录
整个项目的目录
- index.js 是项目启动的主文件
- public/images: 项目的资源目录
- config.json: 项目的配置json
- node_moudles:npm自动生成的依赖包文件夹
- package.json: node的经典文件,npm init会生成
首先你要先运行,来安装express依赖。
npm i express --save
//index.js
const path = require('path')
const express = require('express')
const app = express();
app.get('/', function (req, res) {
res.send('Hello World!');
});
app.listen(8080)
在浏览器上访问8080端口看到有HelloWorld就算成功了!
第二步 :在config.json下配置你的cdn服务器
既然要跳转到cdn服务器,首先就需要一个cdn服务器的baseUrl,在这里我们将这个url配置成一个全局变量放在config.json中,这里我因为没有别的另外的服务器,我就随便写一个,反正只要跳转就好了嘛。
// config.json
{
"baseImageUrl": "https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd="
}
第三步: 配置反向代理逻辑
这一步首先要
npm i express-http-proxy --save
我们首先下载express的代理中间件,这个包里边有个proxy()来完成反向代理。
还是在index.js
const path = require('path')
const express = require('express')
const proxy = require('express-http-proxy')
const baseImageUrl = require('./config.json').baseImageUrl
const proxyBsaeImageUrl = baseImageUrl
? proxy(baseImageUrl, {
proxyReqPathResolver: function(req) {
const newPath = baseImageUrl + req.path;
console.log('newPath: ' + newPath)
return newPath
}
})
: express.static(path.join(__dirname, 'public/images'))
const app = express();
app.use('/images', proxyBsaeImageUrl)
app.listen(8080)
- 这里我们使用了proxyBaseImageUrl来设置跳转的url,使用app.use()方法来跳转
- proxyBaseImageUrl的返回是整个反向代理的关键,首先使用proxy()方法,将头url传入,然后在proxyReqPathResolver中将url拼接完成。proxyReqPathResolver是完成在反向代理之前路径的修改操作等。
最后就是在localhost中敲入/images/xxxxxx,它会跳转到百度中去搜索……整个逻辑都是在proxyReqPathResolver完成的,如果你想要更简单的反向代理逻辑可以写的更完整!