什么是代理及实现代理的7种方案
1、背景
网上查资料时,有些网址访问不了,可以使用正向代理实现访问; 开发过程中,可能会遇到前端跨域的问题,可以用反向代理实现; 后端接口还没写好,前端页面已经写好了,希望自己建立mock数据,当访问后端接口时,实际访问的是前端自己模拟的数据,可以用代理实现。
2、定义
正向代理(代理服务器)
代理服务器(Proxy Server)是一种重要的服务器安全功能,它的工作主要在开放系统互联(OSI)模型的会话层,从而起到防火墙的作用。代理服务器大多被用来连接INTERNET(国际互联网)和INTRANET(局域网)。[1]
反向代理
反向代理服务器位于用户与目标服务器之间,但是对于用户而言,反向代理服务器就相当于目标服务器,即用户直接访问反向代理服务器就可以获得目标服务器的资源。同时,用户不需要知道目标服务器的地址,也无须在用户端作任何设定。反向代理服务器通常可用来作为Web加速,即使用反向代理作为Web服务器的前置机来降低网络和服务器的负载,提高访问效率。[2]
透明代理
透明代理与正向代理比较类似
透明代理的意思是客户端根本不需要知道有代理服务器的存在,它改变你的request fields(报文),并会传送真实IP,多用于路由器的NAT转发中。注意,加密的透明代理则是属于匿名代理,意思是不用设置使用代理了,例如Garden 2程序。[3]
3、区别
| 维度 | 正向代理 | 反向代理 | 透明代理 |
|---|---|---|---|
| 用途 | 作为防火墙;访问被墙的网址;提高访问速度;隐藏客户端真实IP | 负载均衡;隐藏服务器真实IP;提高访问速度;提供安全保障 | 路由器的NAT转发;无法对防火墙进行攻击、屏蔽内部网的细节; |
| 代理谁 | 代理了客户端 | 代理了服务端 | 双向都代理了 |
| 谁架设 | 一般是客户端架设的 | 一般是服务端架设的 | |
| 对哪方未知 | 服务端不知道真正的客户端是谁 | 客户端不知道真正的服务端是谁 | 客户端不知道代理服务器端存在 |
4、设置代理的软件、插件、方法
1)webpack devServer proxy
devServer可以用来快速开发一个应用[8],类似于启动一个新的服务。使用devServer来实现代理的原理:即通过devServerqi动的新服务来作为代理服务器实现请求的代理。因此该方法也可用于解决前端跨域问题。
在webpack.config.js中配置:
devServer: {
contentBase:path.resolve(__dirname,'server'),//Tell the server where to serve content from. This is only necessary if you want to serve static files
open:true,//Tells dev-server to open the browser after server had been started.
port:3040,//端口号
hot:true//热启动
}
或
proxy:{
'/api':'http://localhost:3040/api'
}
或
proxy:{
"/api": {
target: "http://localhost:3000",
pathRewrite: {"^/api" : ""}
}
}
2)node实现代理
如果打包工具不是用的webpack,则无法使用devServe,但可以使用node的http-proxy-middleware或http或request包来模拟devServer实现代理。
http-proxy-middleware
const express = require('express');
const proxyMiddleWare = require('http-proxy-middleware');//代理
const app = express();
//使用反向代理
app.use('/api', proxyMiddleWare(
{
target: 'https://www.baidu.com',changeOrigin:true
}
));
//启动服务 [10]
app.listen('8080');
http
const http=require('http');
http.createServer((req,res)=>{
const options={
host:'www.baidu.com',
port:8086,
path:req.url,
method:req.method
};
http.request(options,(_res)=>{
_res.pipe(req);
}).end();
}).listen(3000,'localhost');
request
const express=require('express');
const request=require('request');
const app=express();
app.use('/',(req,res)=>{
const url='https:www.baidu.com/'+req.url;
req.pipe(request(url)).pipe(res);//把浏览器的请求数据传给request客户端,然后将目标服务器的响应数据传回浏览器[9]
});
app.listen('3000');
3)修改系统文件hosts
在实际开发过程中,可以把localhost改为其他网址进行测试,修改方法如下: 打开终端输入命令:
vim /etc/hosts
添加(中间用 tab 键分隔)
127.0.0.1 www.baidu.com
4)微信开发者工具
在开发微信小程序时,如果需要代理,还可以使用微信开发者工具自带的代理功能,设置方法为: 1) 设置-代理设置-手动设置代理 2) 填入代理地址和端口号
5)chrome插件 SwitchyOmega
SwitchyOmega是Chromium & Firefox 浏览器上的代理扩展插件,根据预先设置好的代理规则,轻松快捷的管理和智能切换多个代理设置,可以避免经常手动切换[5] 核心用法:
- 支持 chrome、chromium、firefox 浏览器,支持在线和离线两种安装方式;
- 支持 http、https、socks4、socks5 四种代理[6]
如何使用
- 新建情景模式,选择代理服务器,填写代理服务器名称
- 填写代理服务器基本信息
- 再新建一个情景模式,这次选择自动切换模式,填写基本信息
当你访问example.com时,实际访问的就是baidu.com
6)Charles
反向代理:Proxy->Reverse Proxies 添加并配置反向代理 透明代理:Proxy->Proxy Settings->Options 设置浏览器/操作系统遇到哪些域名时,使用默认而不用charles [7]
7)whistle
如何配置、使用请参考[11][12]
5、总结
综上所述,通过代码实现的代理、各种工具实现的代理,原理都大同小异,即代理的核心:把对当前地址的访问代理到别的网址而已,实际使用时还需结合使用场景选择哪种方式。
6、参考
[1] https://baike.baidu.com/item/%E4%BB%A3%E7%90%86/3242667 [2] https://baike.baidu.com/item/%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86 [3] https://baike.baidu.com/item/%E9%80%8F%E6%98%8E%E4%BB%A3%E7%90%86 [4] https://cloud.tencent.com/developer/article/1418457 [5] https://www.phpvar.com/archives/4567.html [6] https://blog.mimvp.com/article/29144.html [7] https://www.jianshu.com/p/82f63277d50f [8] https://webpack.js.org/configuration/dev-server/ [9] http://guaji.djjlll.com/News-getInfo-id-929.html [10] https://www.cnblogs.com/xfpBlog/p/11311558.html [11] https://wproxy.org/whistle/install.html [12]https://www.cnblogs.com/fafa-coding/p/10819526.html