前端开发时,经常需要用代理工具Charles或者Fiddler来抓包,或修改接口或替换文件或查看提交数据等,都是非常方便。尤其是做移动端开发时,是不是经常得配置host,或者查看页面请求的数据是否正确,相信我,此时使用Charles的远程代理是一件很幸福的事情。
当我们打开浏览器请求一个页面时候,为什么Charles就能捕获到请求?然而如果chrome使用了SwitchyOmega(配合shadowsocks,翻墙神器)
或者类似的代理插件,此时Charles时捕获不到我们发的请求。
一开始我也很困惑,直到有一次Charles崩溃了,使用装有SwitchyOmega
插件的chrome浏览器可以正常联网,而其他浏览器却不行了。在查看网络设置(网络->代理)中,一不小发现:
我明明没有设置过这个东西啊,看着8888
这个端口号好熟悉啊,额,这个不就是Charles代理设置里面默认的端口号嘛。于是好像突然明白了,Charles是通过这个来监听网页请求,然后抓包,然后就可以对请求进行修改请求参数,断点调试等。
然后再次正常打开Charles,然后正常关闭,果然网页代理设置没有,非chrome浏览器也可以正常联网了。如果打开Charles,手动把代理设置取消,Charles也捕获不了请求了。
既然Charles可以通过设置网络代理来捕获请求,那是否可以自己写一个服务器也实现同样的功能呢?
首先创建一个简单的node服务器:
1 | const http = require('http'); |
然后启动服务器,顺便设置网络的网页代理为服务器的地址127.0.0.1:1338
;接下来访问一个http地址(csdn),因为设置网页代理,当然也可以设置安全网页代理。页面如期待的那样出现了it work
。
代理服务器已经搭建好,但怎么像Charles一样能正常返回请求的页面?
万事开头难,开头了,其实后面确实也就简单了很多。有疑问,但知道具体想做什么,百度一下,不就什么都知道了嘛。参考HTTP 代理原理及实现(一)修改一下源码:
1 | const http = require('http'); |
顺利完成http代理,不信你再访问csdn试试,没有出现页面就是csdn挂了。至于https的可以参考HTTP 代理原理及实现(一)里面有详细的介绍Http代理相关的知识。
嗯嗯,http代理完成了,但是还有个问题啊,为什么上面通过解析req.url
就能获取请求的目标地址,而自己想写一个脚本访问CSDN:
1 | var http = require("http"); |
遍观nodejs官网http.request的可选参数, 都没有提到如何设置。不知道又想不明白,能咋办,上网找呗。
在stackoverflow上找到了一个解决方案,传送–>How can I use an http proxy with node.js http.Client给的方案是设置path
:
1 | var http = require("http"); |
仔细想像好像真的是这么回事啊,如果不设置path
,服务器默端的req.url
就是个/
,这个不就是默认的path
的值嘛。至于设置headers
里面的Host
, 如果不设置会默认为localhost:1338
,也就是请求的服务器的host,这样获得的是一个403页面,如下:
1 | <html> |
参考: