Blog icon indicating copy to clipboard operation
Blog copied to clipboard

什么是代理及实现代理的7种方案

Open yan647 opened this issue 4 years ago • 0 comments

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]

如何使用

  • 新建情景模式,选择代理服务器,填写代理服务器名称 switchyOmega1
  • 填写代理服务器基本信息 switchyOmega2
  • 再新建一个情景模式,这次选择自动切换模式,填写基本信息 switchyOmega3 switchyOmega4 当你访问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

yan647 avatar Feb 28 '21 05:02 yan647