<!DOCTYPE HTML> <html lang="cn" > <head> <meta charset="UTF-8"> <meta content="text/html; charset=utf-8" http-equiv="Content-Type"> <title>简介 · AnyProxy</title> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="description" content=""> <meta name="generator" content="GitBook 3.2.2"> <meta name="author" content="AnyProxy"> <link rel="stylesheet" href="../gitbook/style.css"> <link rel="stylesheet" href="../gitbook/gitbook-plugin-highlight/website.css"> <link rel="stylesheet" href="../gitbook/gitbook-plugin-search/search.css"> <link rel="stylesheet" href="../gitbook/gitbook-plugin-fontsettings/website.css"> <link rel="shortcut icon" href="/assets/favicon.png" type="image/png"> <link rel="stylesheet" href="/assets/website.css"> <script src="/assets/main.js" ></script> </head> <body> <div> </div> <div class="book"> <div class="book-summary"> <div id="book-search-input" role="search"> <input type="text" placeholder="Type to search" /> </div> <nav role="navigation"> <ul class="summary"> <li class="chapter active" data-level="1.1" data-path="./"> <a href="./"> <div class="summary-title-span 简介"> 简介 </div> </a> </li> <li class="chapter " data-level="1.2" data-path="./"> <a href="./#快速开始"> <div class="summary-title-span 快速开始"> 快速开始 </div> </a> <ul class="articles"> <li class="chapter " data-level="1.2.1" data-path="./"> <a href="./#安装"> <div class="summary-title-span 安装"> 安装 </div> </a> </li> <li class="chapter " data-level="1.2.2" data-path="./"> <a href="./#启动"> <div class="summary-title-span 启动"> 启动 </div> </a> </li> <li class="chapter " data-level="1.2.3" data-path="./"> <a href="./#其他命令"> <div class="summary-title-span 其他命令"> 其他命令 </div> </a> </li> <li class="chapter " data-level="1.2.4" data-path="./"> <a href="./#作为npm模块使用"> <div class="summary-title-span 作为npm模块启动"> 作为npm模块启动 </div> </a> </li> </ul> </li> <li class="chapter " data-level="1.3" data-path="./"> <a href="./#代理https"> <div class="summary-title-span 代理HTTPS"> 代理HTTPS </div> </a> </li> <li class="chapter " data-level="1.4" data-path="./"> <a href="./#代理websocket"> <div class="summary-title-span 代理WebSocket"> 代理WebSocket </div> </a> </li> <li class="chapter " data-level="1.5" data-path="./"> <a href="./#rule模块"> <div class="summary-title-span rule模块"> rule模块 </div> </a> <ul class="articles"> <li class="chapter " data-level="1.5.1" data-path="./"> <a href="./#开发示例"> <div class="summary-title-span 开发示例"> 开发示例 </div> </a> </li> <li class="chapter " data-level="1.5.2" data-path="./"> <a href="./#处理流程"> <div class="summary-title-span 处理流程"> 处理流程 </div> </a> </li> <li class="chapter " data-level="1.5.3" data-path="./"> <a href="./#如何引用"> <div class="summary-title-span 如何引用"> 如何引用 </div> </a> </li> </ul> </li> <li class="chapter " data-level="1.6" data-path="./"> <a href="./#rule接口文档"> <div class="summary-title-span rule接口文档"> rule接口文档 </div> </a> <ul class="articles"> <li class="chapter " data-level="1.6.1" data-path="./"> <a href="./#summary"> <div class="summary-title-span rule-title"> summary </div> </a> </li> <li class="chapter " data-level="1.6.2" data-path="./"> <a href="./#beforesendrequest"> <div class="summary-title-span rule-title"> beforeSendRequest </div> </a> </li> <li class="chapter " data-level="1.6.3" data-path="./"> <a href="./#beforesendresponse"> <div class="summary-title-span rule-title"> beforeSendResponse </div> </a> </li> <li class="chapter " data-level="1.6.4" data-path="./"> <a href="./#beforedealhttpsrequest"> <div class="summary-title-span rule-title"> beforeDealHttpsRequest </div> </a> </li> <li class="chapter " data-level="1.6.5" data-path="./"> <a href="./#onerror"> <div class="summary-title-span rule-title"> onError </div> </a> </li> <li class="chapter " data-level="1.6.6" data-path="./"> <a href="./#onconnecterror"> <div class="summary-title-span rule-title"> onConnectError </div> </a> </li> </ul> </li> <li class="chapter " data-level="1.7" data-path="./"> <a href="./#rule样例"> <div class="summary-title-span rule样例"> rule样例 </div> </a> <ul class="articles"> <li class="chapter " data-level="1.7.1" data-path="./"> <a href="./#使用本地数据"> <div class="summary-title-span sample-title"> 使用本地数据 </div> </a> </li> <li class="chapter " data-level="1.7.2" data-path="./"> <a href="./#修改请求头"> <div class="summary-title-span sample-title"> 修改请求头 </div> </a> </li> <li class="chapter " data-level="1.7.3" data-path="./"> <a href="./#修改请求数据"> <div class="summary-title-span sample-title"> 修改请求数据 </div> </a> </li> <li class="chapter " data-level="1.7.4" data-path="./"> <a href="./#修改请求的目标地址"> <div class="summary-title-span sample-title"> 修改请求的目标地址 </div> </a> </li> <li class="chapter " data-level="1.7.5" data-path="./"> <a href="./#修改请求协议"> <div class="summary-title-span sample-title"> 修改请求协议 </div> </a> </li> <li class="chapter " data-level="1.7.6" data-path="./"> <a href="./#修改返回状态码"> <div class="summary-title-span sample-title"> 修改返回状态码 </div> </a> </li> <li class="chapter " data-level="1.7.7" data-path="./"> <a href="./#修改返回头"> <div class="summary-title-span sample-title"> 修改返回头 </div> </a> </li> <li class="chapter " data-level="1.7.8" data-path="./"> <a href="./#修改返回内容并延迟"> <div class="summary-title-span sample-title"> 修改返回内容并延迟 </div> </a> </li> </ul> </li> <li class="chapter " data-level="1.8" data-path="./"> <a href="./#证书配置"> <div class="summary-title-span 证书配置"> 证书配置 </div> </a> <ul class="articles"> <li class="chapter " data-level="1.8.1" data-path="./"> <a href="./#osx系统信任ca证书"> <div class="summary-title-span OSX系统信任CA证书"> OSX系统信任CA证书 </div> </a> </li> <li class="chapter " data-level="1.8.2" data-path="./"> <a href="./#windows系统信任ca证书"> <div class="summary-title-span Windows系统信任CA证书"> Windows系统信任CA证书 </div> </a> </li> <li class="chapter " data-level="1.8.3" data-path="./"> <a href="./#配置osx系统代理"> <div class="summary-title-span 配置OSX系统代理"> 配置OSX系统代理 </div> </a> </li> <li class="chapter " data-level="1.8.4" data-path="./"> <a href="./#配置浏览器http代理"> <div class="summary-title-span 配置浏览器HTTP代理"> 配置浏览器HTTP代理 </div> </a> </li> <li class="chapter " data-level="1.8.5" data-path="./"> <a href="./#ios系统信任ca证书"> <div class="summary-title-span iOS系统信任CA证书"> iOS系统信任CA证书 </div> </a> </li> <li class="chapter " data-level="1.8.6" data-path="./"> <a href="./#ios--103信任ca证书"> <div class="summary-title-span iOS >= 10.3信任CA证书"> iOS >= 10.3信任CA证书 </div> </a> </li> <li class="chapter " data-level="1.8.7" data-path="./"> <a href="./#安卓系统信任ca证书"> <div class="summary-title-span 安卓系统信任CA证书"> 安卓系统信任CA证书 </div> </a> </li> <li class="chapter " data-level="1.8.8" data-path="./"> <a href="./#配置iosandroid系统代理"> <div class="summary-title-span 配置iOS/Android系统代理"> 配置iOS/Android系统代理 </div> </a> </li> </ul> </li> <li class="chapter " data-level="1.9" data-path="./"> <a href="./#faq"> <div class="summary-title-span FAQ"> FAQ </div> </a> </li> <li class="divider"></li> <li> <a href="https://www.gitbook.com" target="blank" class="gitbook-link"> Published with GitBook </a> </li> </ul> </nav> </div> <div class="book-body"> <div class="body-inner"> <div class="book-header" role="navigation"> <!-- Title --> <h1> <i class="fa fa-circle-o-notch fa-spin"></i> <a href="." >简介</a> </h1> </div> <div class="page-wrapper" tabindex="-1" role="main"> <div class="page-inner"> <div id="book-search-results"> <div class="search-noresults"> <section class="normal markdown-section"> <h1 id="anyproxy">AnyProxy</h1> <blockquote> <p>本文档的适用范围是AnyProxy 4.0,欢迎提供反馈</p> </blockquote> <p>Ref: <a href="../en">English Doc</a></p> <p>AnyProxy是一个开放式的HTTP代理服务器。</p> <p>Github主页:<a href="https://github.com/alibaba/anyproxy" target="_blank">https://github.com/alibaba/anyproxy</a></p> <p>主要特性包括:</p> <ul> <li>基于Node.js,开放二次开发能力,允许自定义请求处理逻辑</li> <li>支持Https的解析</li> <li>提供GUI界面,用以观察请求</li> </ul> <p>相比3.x版本,AnyProxy 4.0的主要变化:</p> <ul> <li>规则文件(Rule)全面支持Promise和Generator</li> <li>简化了规则文件内的接口</li> <li>Web版界面重构</li> </ul> <p><img src="https://gw.alipayobjects.com/zos/rmsportal/JoxHUbVhXNedsPUUilnj.gif" width="1275px"></p> <h1 id="快速开始">快速开始</h1> <h2 id="作为全局模块">作为全局模块</h2> <h3 id="安装">安装</h3> <p>对于Debian或者Ubuntu系统,在安装AnyProxy之前,可能还需要安装 <code>nodejs-legacy</code></p> <pre><code class="lang-bash">sudo apt-get install nodejs-legacy </code></pre> <p>然后,安装AnyProxy</p> <pre><code class="lang-bash">npm install -g anyproxy </code></pre> <h3 id="启动">启动</h3> <ul> <li>命令行启动AnyProxy,默认端口号8001</li> </ul> <pre><code class="lang-bash">anyproxy </code></pre> <ul> <li>启动后将终端http代理服务器配置为127.0.0.1:8001即可</li> <li>访问<a href="http://127.0.0.1:8002" target="_blank">http://127.0.0.1:8002</a> ,web界面上能看到所有的请求信息</li> </ul> <h3 id="其他命令">其他命令</h3> <ul> <li>配置启动端口,如1080端口启动</li> </ul> <pre><code class="lang-bash">anyproxy --port 1080 </code></pre> <h2 id="作为npm模块使用">作为npm模块使用</h2> <p>AnyProxy可以作为一个npm模块使用,整合进其他工具。</p> <blockquote> <p>如要启用https解析,请在代理服务器启动前自行调用<code>AnyProxy.utils.certMgr</code>相关方法生成证书,并引导用户信任安装。或引导用户使用<code>anyproxy-ca</code>方法。</p> </blockquote> <ul> <li>引入</li> </ul> <pre><code class="lang-bash">npm i anyproxy --save </code></pre> <ul> <li>使用举例</li> </ul> <pre><code class="lang-js"><span class="hljs-keyword">const</span> AnyProxy = <span class="hljs-built_in">require</span>(<span class="hljs-string">'anyproxy'</span>); <span class="hljs-keyword">const</span> options = { port: <span class="hljs-number">8001</span>, rule: <span class="hljs-built_in">require</span>(<span class="hljs-string">'myRuleModule'</span>), webInterface: { enable: <span class="hljs-literal">true</span>, webPort: <span class="hljs-number">8002</span> }, throttle: <span class="hljs-number">10000</span>, forceProxyHttps: <span class="hljs-literal">false</span>, wsIntercept: <span class="hljs-literal">false</span>, <span class="hljs-comment">// 不开启websocket代理</span> silent: <span class="hljs-literal">false</span> }; <span class="hljs-keyword">const</span> proxyServer = <span class="hljs-keyword">new</span> AnyProxy.ProxyServer(options); proxyServer.on(<span class="hljs-string">'ready'</span>, () => { <span class="hljs-comment">/* */</span> }); proxyServer.on(<span class="hljs-string">'error'</span>, (e) => { <span class="hljs-comment">/* */</span> }); proxyServer.start(); <span class="hljs-comment">//when finished</span> proxyServer.close(); </code></pre> <ul> <li><p>Class: AnyProxy.proxyServer</p> <ul> <li><p>创建代理服务器</p> <pre><code class="lang-js"><span class="hljs-keyword">const</span> proxy = <span class="hljs-keyword">new</span> AnyProxy.proxyServer(options) </code></pre> </li> <li><p><code>options</code></p> <ul> <li><code>port</code> {number} 必选,代理服务器端口</li> <li><code>rule</code> {object} 自定义规则模块</li> <li><code>throttle</code> {number} 限速值,单位kb/s,默认不限速</li> <li><code>forceProxyHttps</code> {boolean} 是否强制拦截所有的https,忽略规则模块的返回,默认<code>false</code></li> <li><code>silent</code> {boolean} 是否屏蔽所有console输出,默认<code>false</code></li> <li><code>dangerouslyIgnoreUnauthorized</code> {boolean} 是否忽略请求中的证书错误,默认<code>false</code></li> <li><code>wsIntercept</code> {boolean} 是否开启websocket代理,默认<code>false</code></li> <li><code>webInterface</code> {object} web版界面配置<ul> <li><code>enable</code> {boolean} 是否启用web版界面,默认<code>false</code></li> <li><code>webPort</code> {number} web版界面端口号,默认<code>8002</code></li> </ul> </li> </ul> </li> <li><p>Event: <code>ready</code></p> <ul> <li>代理服务器启动完成</li> <li>示例</li> </ul> <pre><code class="lang-js">proxy.on(<span class="hljs-string">'ready'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ }) </code></pre> </li> <li><p>Event: <code>error</code></p> <ul> <li>代理服务器发生错误</li> <li>示例</li> </ul> <pre><code class="lang-js">proxy.on(<span class="hljs-string">'error'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ }) </code></pre> </li> <li><p>Method: <code>start</code></p> <ul> <li>启动代理服务器</li> <li>示例</li> </ul> <pre><code class="lang-js">proxy.start(); </code></pre> </li> <li><p>Method: <code>close</code></p> <ul> <li>关闭代理服务器</li> <li>示例</li> </ul> <pre><code class="lang-js">proxy.close(); </code></pre> </li> </ul> </li> <li><p>AnyProxy.utils.systemProxyMgr</p> <ul> <li>管理系统的全局代理配置,方法调用时可能会弹出密码框</li> <li>使用示例</li> </ul> <pre><code class="lang-js"><span class="hljs-comment">// 配置127.0.0.1:8001为全局http代理服务器</span> AnyProxy.utils.systemProxyMgr.enableGlobalProxy(<span class="hljs-string">'127.0.0.1'</span>, <span class="hljs-string">'8001'</span>); <span class="hljs-comment">// 关闭全局代理服务器</span> AnyProxy.utils.systemProxyMgr.disableGlobalProxy(); </code></pre> </li> <li><p>AnyProxy.utils.certMgr</p> <ul> <li>管理AnyProxy的证书</li> <li><code>AnyProxy.utils.certMgr.ifRootCAFileExists()</code><ul> <li>校验系统内是否存在AnyProxy的根证书</li> </ul> </li> <li><code>AnyProxy.utils.certMgr.generateRootCA(callback)</code><ul> <li>生成AnyProxy的rootCA,完成后请引导用户信任.crt文件</li> </ul> </li> <li>样例</li> </ul> <pre><code class="lang-js"> <span class="hljs-keyword">const</span> AnyProxy = <span class="hljs-built_in">require</span>(<span class="hljs-string">'AnyProxy'</span>); <span class="hljs-keyword">const</span> exec = <span class="hljs-built_in">require</span>(<span class="hljs-string">'child_process'</span>).exec; <span class="hljs-keyword">if</span> (!AnyProxy.utils.certMgr.ifRootCAFileExists()) { AnyProxy.utils.certMgr.generateRootCA((error, keyPath) => { <span class="hljs-comment">// let users to trust this CA before using proxy</span> <span class="hljs-keyword">if</span> (!error) { <span class="hljs-keyword">const</span> certDir = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>).dirname(keyPath); <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'The cert is generated at'</span>, certDir); <span class="hljs-keyword">const</span> isWin = <span class="hljs-regexp">/^win/</span>.test(process.platform); <span class="hljs-keyword">if</span> (isWin) { exec(<span class="hljs-string">'start .'</span>, { cwd: certDir }); } <span class="hljs-keyword">else</span> { exec(<span class="hljs-string">'open .'</span>, { cwd: certDir }); } } <span class="hljs-keyword">else</span> { <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'error when generating rootCA'</span>, error); } }); } </code></pre> </li> </ul> <h1 id="代理https">代理HTTPS</h1> <ul> <li>AnyProxy默认不对https请求做处理,如需看到明文信息,需要配置CA证书</li> </ul> <blockquote> <p>解析https请求的原理是中间人攻击(man-in-the-middle),用户必须信任AnyProxy生成的CA证书,才能进行后续流程</p> </blockquote> <ul> <li>生成证书并解析所有https请求</li> </ul> <pre><code class="lang-bash">anyproxy-ca <span class="hljs-comment">#生成rootCA证书,生成后需要手动信任</span> anyproxy --intercept <span class="hljs-comment">#启动AnyProxy,并解析所有https请求</span> </code></pre> <ul> <li><a href="#证书配置">附录:如何信任CA证书</a></li> </ul> <h1 id="代理websocket">代理WebSocket</h1> <pre><code class="lang-bash">anyproxy --ws-intercept </code></pre> <blockquote> <p>当启用<code>HTTPS</code>代理时,<code>wss</code>也会被代理,但是不会被AnyProxy记录。需要开启<code>--ws-intercept</code>后才会从界面上看到相应内容。</p> </blockquote> <h1 id="rule模块">rule模块</h1> <p>AnyProxy提供了二次开发的能力,你可以用js编写自己的规则模块(rule),来自定义网络请求的处理逻辑。</p> <blockquote> <p>注意:引用规则前,请务必确保文件来源可靠,以免发生安全问题</p> </blockquote> <p>规则模块的能力范围包括:</p> <ul> <li>拦截并修改正在发送的请求<ul> <li>可修改内容包括请求头(request header),请求体(request body),甚至是请求的目标地址等</li> </ul> </li> <li>拦截并修改服务端响应<ul> <li>可修改的内容包括http状态码(status code)、响应头(response header)、响应内容等</li> </ul> </li> <li>拦截https请求,对内容做修改<ul> <li>本质是中间人攻击(man-in-the-middle attack),需要客户端提前信任AnyProxy生成的CA</li> </ul> </li> </ul> <h3 id="开发示例">开发示例</h3> <ul> <li><p>举例</p> <ul> <li>需要编写一个规则模块,在 GET <a href="http://httpbin.org/user-agent" target="_blank">http://httpbin.org/user-agent</a> 的返回值里加上测试信息,并延迟5秒返回</li> </ul> </li> <li><p>Step 1,编写规则</p> <pre><code class="lang-js"><span class="hljs-comment">// file: sample.js</span> <span class="hljs-built_in">module</span>.exports = { summary: <span class="hljs-string">'a rule to hack response'</span>, *beforeSendResponse(requestDetail, responseDetail) { <span class="hljs-keyword">if</span> (requestDetail.url === <span class="hljs-string">'http://httpbin.org/user-agent'</span>) { <span class="hljs-keyword">const</span> newResponse = responseDetail.response; newResponse.body += <span class="hljs-string">'- AnyProxy Hacked!'</span>; <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>((resolve, reject) => { setTimeout(() => { <span class="hljs-comment">// delay</span> resolve({ response: newResponse }); }, <span class="hljs-number">5000</span>); }); } }, }; </code></pre> </li> <li><p>Step 2, 启动AnyProxy,加载规则</p> <ul> <li>运行 <code>anyproxy --rule sample.js</code></li> </ul> </li> <li><p>Step 3, 测试规则</p> <ul> <li><p>用curl测试</p> <pre><code class="lang-bash">curl http://httpbin.org/user-agent --proxy http://127.0.0.1:8001 </code></pre> </li> <li><p>用浏览器测试:配置浏览器http代理为 127.0.0.1:8001,访问 <a href="http://httpbin.org/user-agent" target="_blank">http://httpbin.org/user-agent</a></p> </li> <li><p>经过代理服务器后,期望的返回如下</p> </li> </ul> <pre><code>{ "user-agent": "curl/7.43.0" } - AnyProxy Hacked! </code></pre></li> <li><p>Step 4, 查看请求信息</p> <ul> <li>浏览器访问<a href="http://127.0.0.1:8002" target="_blank">http://127.0.0.1:8002</a> ,界面上能看到刚才的请求信息</li> </ul> </li> </ul> <h3 id="处理流程">处理流程</h3> <ul> <li>处理流程图如下</li> </ul> <p><img src="https://zos.alipayobjects.com/rmsportal/TWyNuSJtEZBdrdcOMRjE.png" width="550"></p> <ul> <li><p>当http请求经过代理服务器时,具体处理过程是:</p> <ul> <li>收集请求所有请求参数,包括method, header, body等</li> <li>AnyProxy调用规则模块<code>beforeSendRequest</code>方法,由模块做处理,返回新的请求参数,或返回响应内容</li> <li>如果<code>beforeSendRequest</code>返回了响应内容,则立即把此响应返回到客户端(而不再发送到真正的服务端),流程结束。</li> <li>根据请求参数,向服务端发出请求,接收服务端响应。</li> <li>调用规则模块<code>beforeSendResponse</code>方法,由模块对响应内容进行处理</li> <li>把响应信息返回给客户端</li> </ul> </li> <li><p>当代理服务器收到https请求时,AnyProxy可以替换证书,对请求做明文解析。</p> <ul> <li>调用规则模块<code>beforeDealHttpsRequest</code>方法,如果返回<code>true</code>,会明文解析这个请求,其他请求不处理</li> <li>被明文解析后的https请求,处理流程同http一致。未明文解析请求不会再进入规则模块做处理。</li> </ul> </li> </ul> <h3 id="如何引用">如何引用</h3> <p>如下几种方案都可以用来引用规则模块:</p> <ul> <li>使用本地路径<pre><code class="lang-bash">anyproxy --rule ./rule.js </code></pre> </li> <li><p>使用在线地址</p> <pre><code class="lang-bash">anyproxy --rule https://sample.com/rule.js </code></pre> </li> <li><p>使用npm包</p> <ul> <li>AnyProxy使用<code>require()</code>加载本地规则,你可以在参数里传入一个本地的npm包路径,或是某个全局安装的npm包</li> </ul> <pre><code class="lang-bash">anyproxy --rule ./myRulePkg/ <span class="hljs-comment">#本地包</span> npm i -g myRulePkg && anyproxy --rule myRulePkg <span class="hljs-comment">#全局包</span> </code></pre> </li> </ul> <h1 id="rule接口文档">rule接口文档</h1> <p>规则模块应该符合cmd规范,一个典型的规则模块代码结构如下。模块中所有方法都是可选的,只需实现业务感兴趣的部分即可。</p> <pre><code class="lang-js"><span class="hljs-built_in">module</span>.exports = { <span class="hljs-comment">// 模块介绍</span> summary: <span class="hljs-string">'my customized rule for AnyProxy'</span>, <span class="hljs-comment">// 发送请求前拦截处理</span> *beforeSendRequest(requestDetail) { <span class="hljs-comment">/* ... */</span> }, <span class="hljs-comment">// 发送响应前处理</span> *beforeSendResponse(requestDetail, responseDetail) { <span class="hljs-comment">/* ... */</span> }, <span class="hljs-comment">// 是否处理https请求</span> *beforeDealHttpsRequest(requestDetail) { <span class="hljs-comment">/* ... */</span> }, <span class="hljs-comment">// 请求出错的事件</span> *onError(requestDetail, error) { <span class="hljs-comment">/* ... */</span> }, <span class="hljs-comment">// https连接服务器出错</span> *onConnectError(requestDetail, error) { <span class="hljs-comment">/* ... */</span> } }; </code></pre> <blockquote> <p>规则文件中,除了summary,都是由 <a href="https://www.npmjs.com/package/co" target="_blank">co</a> 驱动的,函数需要满足yieldable。可以返回promise或使用generator函数。</p> </blockquote> <h3 id="summary">summary</h3> <h4 id="summary-string--summarystring">summary(): string | summary:string</h4> <ul> <li>规则模块的介绍文案,用于AnyProxy提示用户, 可以是一个函数,也可以是一个普通的字符串</li> </ul> <h3 id="beforesendrequest">beforeSendRequest</h3> <h4 id="beforesendrequestrequestdetail">beforeSendRequest(requestDetail)</h4> <ul> <li>AnyProxy向服务端发送请求前,会调用<code>beforeSendRequest</code>,并带上参数<code>requestDetail</code></li> <li><code>requestDetail</code><ul> <li><code>protocol</code> {string} 请求使用的协议,http或者https</li> <li><code>requestOptions</code> {object} 即将发送的请求配置,供require('http').request作为使用。详见:<a href="https://nodejs.org/api/http.html#http_http_request_options_callback" target="_blank">https://nodejs.org/api/http.html#http_http_request_options_callback</a></li> <li><code>requestData</code> {object} 请求Body</li> <li><code>url</code> {string} 请求url</li> <li><code>_req</code> {object} 请求的原始request</li> </ul> </li> <li><p>举例:请求 <em>anyproxy.io</em> 时,<code>requestDetail</code>参数内容大致如下</p> <pre><code class="lang-js">{ protocol: <span class="hljs-string">'http'</span>, url: <span class="hljs-string">'http://anyproxy.io/'</span>, requestOptions: { hostname: <span class="hljs-string">'anyproxy.io'</span>, port: <span class="hljs-number">80</span>, path: <span class="hljs-string">'/'</span>, method: <span class="hljs-string">'GET'</span>, headers: { Host: <span class="hljs-string">'anyproxy.io'</span>, <span class="hljs-string">'Proxy-Connection'</span>: <span class="hljs-string">'keep-alive'</span>, <span class="hljs-string">'User-Agent'</span>: <span class="hljs-string">'...'</span> } }, requestData: <span class="hljs-string">'...'</span>, _req: { <span class="hljs-comment">/* ... */</span>} } </code></pre> </li> <li><p>以下几种返回都是合法的</p> <ul> <li>不做任何处理,返回null</li> </ul> <pre><code class="lang-js"><span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>; </code></pre> <ul> <li>修改请求协议,如强制改用https发起请求</li> </ul> <pre><code class="lang-js"><span class="hljs-keyword">return</span> { protocol: <span class="hljs-string">'https'</span> }; </code></pre> <ul> <li>修改请求参数</li> </ul> <pre><code class="lang-js"><span class="hljs-keyword">var</span> newOption = <span class="hljs-built_in">Object</span>.assign({}, requestDetail.requestOptions); newOption.path = <span class="hljs-string">'/redirect/to/another/path'</span>; <span class="hljs-keyword">return</span> { requestOptions: newOption }; </code></pre> <ul> <li>修改请求body</li> </ul> <pre><code class="lang-js"><span class="hljs-keyword">return</span> { requestData: <span class="hljs-string">'my new request data'</span> <span class="hljs-comment">//这里也可以同时加上requestOptions</span> }; </code></pre> <ul> <li>直接返回客户端,不再发起请求,其中<code>statusCode</code> <code>header</code> 是必选字段</li> </ul> <pre><code class="lang-js"><span class="hljs-keyword">return</span> { response: { statusCode: <span class="hljs-number">200</span>, header: { <span class="hljs-string">'content-type'</span>: <span class="hljs-string">'text/html'</span> }, body: <span class="hljs-string">'this could be a <string> or <buffer>'</span> } }; </code></pre> </li> </ul> <h3 id="beforesendresponse">beforeSendResponse</h3> <h4 id="beforesendresponserequestdetail-responsedetail">beforeSendResponse(requestDetail, responseDetail)</h4> <ul> <li>AnyProxy向客户端发送请求前,会调用<code>beforeSendResponse</code>,并带上参数<code>requestDetail</code> <code>responseDetail</code></li> <li><code>requestDetail</code> 同<code>beforeSendRequest</code>中的参数</li> <li><code>responseDetail</code><ul> <li><code>response</code> {object} 服务端的返回信息,包括<code>statusCode</code> <code>header</code> <code>body</code>三个字段</li> <li><code>_res</code> {object} 原始的服务端返回对象</li> </ul> </li> <li><p>举例,请求 <em>anyproxy.io</em> 时,<code>responseDetail</code>参数内容大致如下</p> <pre><code class="lang-js">{ response: { statusCode: <span class="hljs-number">200</span>, header: { <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'image/gif'</span>, Connection: <span class="hljs-string">'close'</span>, <span class="hljs-string">'Cache-Control'</span>: <span class="hljs-string">'...'</span> }, body: <span class="hljs-string">'...'</span> }, _res: { <span class="hljs-comment">/* ... */</span> } } </code></pre> </li> <li><p>以下几种返回都是合法的</p> <ul> <li>不做任何处理,返回null</li> </ul> <pre><code class="lang-js"><span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>; </code></pre> <ul> <li>修改返回的状态码</li> </ul> <pre><code class="lang-js"><span class="hljs-keyword">var</span> newResponse = <span class="hljs-built_in">Object</span>.assign({}, responseDetail.response); newResponse.statusCode = <span class="hljs-number">404</span>; <span class="hljs-keyword">return</span> { response: newResponse }; </code></pre> <ul> <li>修改返回的内容</li> </ul> <pre><code class="lang-js"><span class="hljs-keyword">var</span> newResponse = <span class="hljs-built_in">Object</span>.assign({}, responseDetail.response); newResponse.body += <span class="hljs-string">'--from anyproxy--'</span>; <span class="hljs-keyword">return</span> { response: newResponse }; </code></pre> </li> </ul> <h3 id="beforedealhttpsrequest">beforeDealHttpsRequest</h3> <h4 id="beforedealhttpsrequestrequestdetail">beforeDealHttpsRequest(requestDetail)</h4> <ul> <li>AnyProxy收到https请求时,会调用<code>beforeDealHttpsRequest</code>,并带上参数<code>requestDetail</code></li> <li>如果配置了全局解析https的参数,则AnyProxy会略过这个调用</li> <li>只有返回<code>true</code>时,AnyProxy才会尝试替换证书、解析https。否则只做数据流转发,无法看到明文数据。</li> <li>注意:https over http的代理模式中,这里的request是CONNECT请求</li> <li><code>requestDetail</code><ul> <li><code>host</code> {string} 请求目标的Host,受制于协议,这里无法获取完整url</li> <li><code>_req</code> {object} 请求的原始request</li> </ul> </li> <li>返回值<ul> <li><code>true</code>或者<code>false</code>,表示是否需要AnyProxy替换证书并解析https</li> </ul> </li> </ul> <h3 id="onerror">onError</h3> <h4 id="onerrorrequestdetail-error">onError(requestDetail, error)</h4> <ul> <li>在请求处理过程中发生错误时,AnyProxy会调用<code>onError</code>方法,并提供对应的错误信息</li> <li>多数场景下,错误会在请求目标服务器的时候发生,比如DNS解析失败、请求超时等</li> <li><code>requestDetail</code> 同<code>beforeSendRequest</code>中的参数</li> <li><p>以下几种返回都是合法的</p> <ul> <li>不做任何处理。此时AnyProxy会返回一个默认的错误页。</li> </ul> <pre><code class="lang-js"><span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>; </code></pre> <ul> <li>返回自定义错误页</li> </ul> <pre><code class="lang-js"><span class="hljs-keyword">return</span> { response: { statusCode: <span class="hljs-number">200</span>, header: { <span class="hljs-string">'content-type'</span>: <span class="hljs-string">'text/html'</span> }, body: <span class="hljs-string">'this could be a <string> or <buffer>'</span> } }; </code></pre> </li> </ul> <h3 id="onconnecterror">onConnectError</h3> <h4 id="onconnecterrorrequestdetail-error">onConnectError(requestDetail, error)</h4> <ul> <li>AnyProxy在与目标HTTPS服务器建立连接的过程中,如果发生错误,AnyProxy会调用这个方法</li> <li><code>requestDetail</code> 同<code>beforeDealHttpsRequest</code>中的参数</li> <li>此处无法控制向客户端的返回信息,无需返回值。</li> </ul> <h1 id="rule样例">rule样例</h1> <ul> <li>这里提供一些样例,来讲解规则模块的常见用法</li> <li>你可以通过 <code>anyproxy --rule http://....js</code> 来加载模块并体验</li> <li>用curl发请求测试的方法如下<ul> <li>直接请求服务器:<code>curl http://httpbin.org/</code></li> <li>通过代理服务器请求:<code>curl http://httpbin.org/ --proxy http://127.0.0.1:8001</code></li> </ul> </li> </ul> <h3 id="使用本地数据">使用本地数据</h3> <ul> <li>拦截发送到 <a href="http://httpbin.org" target="_blank">http://httpbin.org</a> 的请求,使用本地数据代替服务端返回</li> </ul> <pre><code class="lang-bash">anyproxy --rule rule_sample/sample_use_<span class="hljs-built_in">local</span>_response.js </code></pre> <pre><code class="lang-js"><span class="hljs-comment">/* sample: intercept all requests toward httpbin.org, use a local response test: curl http://httpbin.org/user-agent --proxy http://127.0.0.1:8001 */</span> <span class="hljs-built_in">module</span>.exports = { *beforeSendRequest(requestDetail) { <span class="hljs-keyword">const</span> localResponse = { statusCode: <span class="hljs-number">200</span>, header: { <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/json'</span> }, body: <span class="hljs-string">'{"hello": "this is local response"}'</span> }; <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org'</span>) === <span class="hljs-number">0</span>) { <span class="hljs-keyword">return</span> { response: localResponse }; } }, }; </code></pre> <h3 id="修改请求头">修改请求头</h3> <ul> <li>修改发送到 httpbin.org 的user-agent</li> </ul> <pre><code class="lang-bash">anyproxy --rule rule_sample/sample_modify_request_header.js </code></pre> <pre><code class="lang-js"><span class="hljs-comment">/* sample: modify the user-agent in requests toward httpbin.org test: curl http://httpbin.org/user-agent --proxy http://127.0.0.1:8001 */</span> <span class="hljs-built_in">module</span>.exports = { *beforeSendRequest(requestDetail) { <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org'</span>) === <span class="hljs-number">0</span>) { <span class="hljs-keyword">const</span> newRequestOptions = requestDetail.requestOptions; newRequestOptions.headers[<span class="hljs-string">'User-Agent'</span>] = <span class="hljs-string">'AnyProxy/0.0.0'</span>; <span class="hljs-keyword">return</span> { requestOptions: newRequestOptions }; } }, }; </code></pre> <h3 id="修改请求数据">修改请求数据</h3> <ul> <li>修改发送到 <a href="http://httpbin.org/post" target="_blank">http://httpbin.org/post</a> 的post数据</li> </ul> <pre><code class="lang-bash">anyproxy --rule rule_sample/sample_modify_request_data.js </code></pre> <pre><code class="lang-js"><span class="hljs-comment">/* sample: modify the post data towards http://httpbin.org/post test: curl -H "Content-Type: text/plain" -X POST -d 'original post data' http://httpbin.org/post --proxy http://127.0.0.1:8001 expected response: { "data": "i-am-anyproxy-modified-post-data" } */</span> <span class="hljs-built_in">module</span>.exports = { summary: <span class="hljs-string">'Rule to modify request data'</span>, *beforeSendRequest(requestDetail) { <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org/post'</span>) === <span class="hljs-number">0</span>) { <span class="hljs-keyword">return</span> { requestData: <span class="hljs-string">'i-am-anyproxy-modified-post-data'</span> }; } }, }; </code></pre> <h3 id="修改请求的目标地址">修改请求的目标地址</h3> <ul> <li>把所有发送到 <a href="http://httpbin.org/" target="_blank">http://httpbin.org/</a> 的请求全部改到 <a href="http://httpbin.org/user-agent" target="_blank">http://httpbin.org/user-agent</a></li> </ul> <pre><code class="lang-bash">anyproxy --rule rule_sample/sample_modify_request_path.js </code></pre> <pre><code class="lang-js"><span class="hljs-comment">/* sample: redirect all https://httpbin.org/user-agent requests to http://localhost:8008/index.html test: curl https://httpbin.org/user-agent --proxy http://127.0.0.1:8001 expected response: 'hello world' from 127.0.0.1:8001/index.html */</span> <span class="hljs-built_in">module</span>.exports = { *beforeSendRequest(requestDetail) { <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'https://httpbin.org/user-agent'</span>) === <span class="hljs-number">0</span>) { <span class="hljs-keyword">const</span> newRequestOptions = requestDetail.requestOptions; requestDetail.protocol = <span class="hljs-string">'http'</span>; newRequestOptions.hostname = <span class="hljs-string">'127.0.0.1'</span> newRequestOptions.port = <span class="hljs-string">'8008'</span>; newRequestOptions.path = <span class="hljs-string">'/index.html'</span>; newRequestOptions.method = <span class="hljs-string">'GET'</span>; <span class="hljs-keyword">return</span> requestDetail; } }, *beforeDealHttpsRequest(requestDetail) { <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>; } }; </code></pre> <h3 id="修改请求协议">修改请求协议</h3> <ul> <li>把用http协议请求的 <a href="http://httpbin.org" target="_blank">http://httpbin.org</a> 改成https并发送</li> </ul> <pre><code class="lang-bash">anyproxy --rule rule_sample/sample_modify_request_protocol.js </code></pre> <pre><code class="lang-js"><span class="hljs-comment">/* sample: redirect all http requests of httpbin.org to https test: curl 'http://httpbin.org/get?show_env=1' --proxy http://127.0.0.1:8001 expected response: { "X-Forwarded-Protocol": "https" } */</span> <span class="hljs-built_in">module</span>.exports = { *beforeSendRequest(requestDetail) { <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org'</span>) === <span class="hljs-number">0</span>) { <span class="hljs-keyword">const</span> newOption = requestDetail.requestOptions; newOption.port = <span class="hljs-number">443</span>; <span class="hljs-keyword">return</span> { protocol: <span class="hljs-string">'https'</span>, requestOptions: newOption }; } } }; </code></pre> <h3 id="修改返回状态码">修改返回状态码</h3> <ul> <li>把 所有<a href="http://httpbin.org" target="_blank">http://httpbin.org</a> 的返回状态码都改成404</li> </ul> <pre><code class="lang-bash">anyproxy --rule rule_sample/sample_modify_response_statuscode.js </code></pre> <pre><code class="lang-js"><span class="hljs-comment">/* sample: modify all status code of http://httpbin.org/ to 404 test: curl -I 'http://httpbin.org/user-agent' --proxy http://127.0.0.1:8001 expected response: HTTP/1.1 404 Not Found */</span> <span class="hljs-built_in">module</span>.exports = { *beforeSendResponse(requestDetail, responseDetail) { <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org'</span>) === <span class="hljs-number">0</span>) { <span class="hljs-keyword">const</span> newResponse = responseDetail.response; newResponse.statusCode = <span class="hljs-number">404</span>; <span class="hljs-keyword">return</span> { response: newResponse }; } } }; </code></pre> <h3 id="修改返回头">修改返回头</h3> <ul> <li>在 <a href="http://httpbin.org/user-agent" target="_blank">http://httpbin.org/user-agent</a> 的返回头里加上 X-Proxy-By:AnyProxy</li> </ul> <pre><code class="lang-bash">anyproxy --rule rule_sample/sample_modify_response_header.js </code></pre> <pre><code class="lang-js"><span class="hljs-comment">/* sample: modify response header of http://httpbin.org/user-agent test: curl -I 'http://httpbin.org/user-agent' --proxy http://127.0.0.1:8001 expected response: X-Proxy-By: AnyProxy */</span> <span class="hljs-built_in">module</span>.exports = { *beforeSendResponse(requestDetail, responseDetail) { <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'http://httpbin.org/user-agent'</span>) === <span class="hljs-number">0</span>) { <span class="hljs-keyword">const</span> newResponse = responseDetail.response; newResponse.header[<span class="hljs-string">'X-Proxy-By'</span>] = <span class="hljs-string">'AnyProxy'</span>; <span class="hljs-keyword">return</span> { response: newResponse }; } } }; </code></pre> <h3 id="修改返回内容并延迟">修改返回内容并延迟</h3> <ul> <li>在 <a href="http://httpbin.org/user-agent" target="_blank">http://httpbin.org/user-agent</a> 的返回最后追加AnyProxy的签名,并延迟5秒</li> </ul> <pre><code class="lang-bash">anyproxy --rule rule_sample/sample_modify_response_data.js </code></pre> <pre><code class="lang-js"><span class="hljs-comment">/* sample: modify response data of http://httpbin.org/user-agent test: curl 'http://httpbin.org/user-agent' --proxy http://127.0.0.1:8001 expected response: { "user-agent": "curl/7.43.0" } -- AnyProxy Hacked! -- */</span> <span class="hljs-built_in">module</span>.exports = { *beforeSendResponse(requestDetail, responseDetail) { <span class="hljs-keyword">if</span> (requestDetail.url === <span class="hljs-string">'http://httpbin.org/user-agent'</span>) { <span class="hljs-keyword">const</span> newResponse = responseDetail.response; newResponse.body += <span class="hljs-string">'-- AnyProxy Hacked! --'</span>; <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>((resolve, reject) => { setTimeout(() => { <span class="hljs-comment">// delay the response for 5s</span> resolve({ response: newResponse }); }, <span class="hljs-number">5000</span>); }); } }, }; </code></pre> <h1 id="证书配置">证书配置</h1> <h3 id="osx系统信任ca证书">OSX系统信任CA证书</h3> <ul> <li>类似这种报错都是因为系统没有信任AnyProxy生成的CA所造成的</li> </ul> <p><img src="https://zos.alipayobjects.com/rmsportal/CBkLGYgvoHAYwNVAYkpk.png" width="450"></p> <blockquote> <p>警告:CA证书和系统安全息息相关,建议亲自生成,并妥善保管</p> </blockquote> <p>安装CA:</p> <ul> <li><p>双击打开<em>rootCA.crt</em></p> </li> <li><p>确认将证书添加到login或system</p> </li> </ul> <p><img src="https://zos.alipayobjects.com/rmsportal/bCwNUFFpvsmVuljQKrIk.png" width="350"></p> <ul> <li>找到刚刚导入的AnyProxy证书,配置为信任(Always Trust)</li> </ul> <p><img src="https://zos.alipayobjects.com/rmsportal/HOmEElNGdoZEWFMLsTNT.png" width="700"></p> <h3 id="windows系统信任ca证书">Windows系统信任CA证书</h3> <p><img src="https://t.alipayobjects.com/tfscom/T1D3hfXeFtXXXXXXXX.jpg" width="700"></p> <h3 id="配置osx系统代理">配置OSX系统代理</h3> <ul> <li>在wifi高级设置中,配置http代理即可</li> </ul> <p><img src="https://zos.alipayobjects.com/rmsportal/vduwhobSTypTfgniBvoa.png" width="500"></p> <h3 id="配置浏览器http代理">配置浏览器HTTP代理</h3> <ul> <li>以Chrome的<a href="https://chrome.google.com/webstore/detail/padekgcemlokbadohgkifijomclgjgif" target="_blank">SwitchyOmega插件</a>为例</li> </ul> <p><img src="https://zos.alipayobjects.com/rmsportal/jIPZrKmqXRaSledQeJUJ.png" width="500"></p> <h3 id="ios系统信任ca证书">iOS系统信任CA证书</h3> <ul> <li>点击web ui中的 <em>Root CA</em>,按提示扫描二维码即可安装</li> </ul> <p><img src="https://zos.alipayobjects.com/rmsportal/BrugmMelGVysLDOIBblj.png" width="260"></p> <h3 id="ios--103信任ca证书">iOS >= 10.3信任CA证书</h3> <ul> <li>除了上述证书安装过程,还需要在 <em>设置->通用->关于本机->证书信任设置</em> 中把AnyProxy证书的开关打开,否则safari将报错。</li> </ul> <p><img src="https://zos.alipayobjects.com/rmsportal/hVWkXHrzHmOKOtCKGUWx.png" width="500"></p> <h3 id="安卓系统信任ca证书">安卓系统信任CA证书</h3> <p>首先和iOS类似,需要先扫描证书的二维码进行下载。然后不同的安卓系统安装证书的方式可能有所不同,但是安装的步骤是类似的,我们列举了几种类型。</p> <ul> <li>下载后的证书可以直接单击打开并安装,这种方式是最简单的,直接安装即可</li> <li>证书下载到指定目录后,需要从其他入口进行安装,包括:<ul> <li>设置 -> 安全性与位置信息 -> 加密与凭据 -> 从存储设备安装。找到你下载的证书文件,进行安装</li> <li>设置 -> 安全 -> 从SD卡安装证书。找到你下载的证书文件,进行安装</li> </ul> </li> </ul> <h3 id="配置iosandroid系统代理">配置iOS/Android系统代理</h3> <ul> <li><p>代理服务器都在wifi设置中配置</p> </li> <li><p>iOS HTTP代理配置</p> </li> </ul> <p><img src="https://zos.alipayobjects.com/rmsportal/tLGqIozhffTccUgPakuw.png" width="260"></p> <ul> <li>Android HTTP代理配置</li> </ul> <p><img src="https://zos.alipayobjects.com/rmsportal/YQtbQYVNuOszZGdAOauU.png" width="260"></p> <h1 id="faq">FAQ</h1> <h4 id="q-为什么https请求不能进入处理函数?">Q: 为什么https请求不能进入处理函数?</h4> <p> A: 以下任意一项都能用来改变https的处理特性:</p> <pre><code> 1. 命令行启动AnyProxy时配置`--intercept`参数,按npm模块启动时配置`forceProxyHttps`参数,所有Https请求都会被替换证书并解析 2. 规则文件内提供`beforeDealHttpsRequest`方法,返回 *true* 的https请求会被解析 </code></pre><h4 id="q-提示-function-is-not-yieldable">Q: 提示 <em>function is not yieldable</em></h4> <ul> <li>A: 规则模块是用 <a href="https://www.npmjs.com/package/co" target="_blank">co</a> 驱动的,函数需要满足yieldable。可以使用generator方法或是返回Promise。</li> </ul> <h4 id="q-the-connection-is-not-private">Q: The connection is not private</h4> <p>当访问特定的HTTPS站点,AnyProxy会提示该站点不是一个安全的网站,这通常是因为站点的证书设置不能被正确识别导致的(比如,站点的证书是自签发的)。如果您信任该网站,可以用以下方式来继续访问:</p> <ul> <li><p>命令行直接启动</p> <p>通过启动参数 <code>--ignore-unauthorized-ssl</code> 来忽略证书认证的错误。需要注意的是,该参数是全局生效的,如果你在此期间访问了其他未知的网站,他们的证书问题也会被忽略,这可能会带来安全隐患。</p> <pre><code class="lang-bash">anyproxy -i --ignore-unauthorized-ssl </code></pre> </li> <li><p>在Nodejs代码中启动</p> <p>在构造AnyProxy实例的时候,传入参数<code>dangerouslyIgnoreUnauthorized:true</code>, 如下:</p> <pre><code class="lang-js"> <span class="hljs-keyword">const</span> options = { ..., dangerouslyIgnoreUnauthorized: <span class="hljs-literal">true</span> }; <span class="hljs-keyword">const</span> anyproxyIns = <span class="hljs-keyword">new</span> AnyProxy.ProxyCore(options); anyproxyIns.start(); </code></pre> <p><em>通过这种方式初始化的AnyProxy,其配置也是全局性的,所有网站的证书问题都会被忽略</em></p> </li> <li><p>通过自定义的Rule来修改</p> <p>我们自然也可以借助自定义的Rule来实现这个效果,而且我们还可以控制到只允许指定网址的证书错误,对不在列表的网址,进行证书的强验证。</p> <pre><code class="lang-js"><span class="hljs-built_in">module</span>.exports = { *beforeSendRequest(requestDetail) { <span class="hljs-keyword">if</span> (requestDetail.url.indexOf(<span class="hljs-string">'https://the-site-you-know.com'</span>) === <span class="hljs-number">0</span>) { <span class="hljs-keyword">const</span> newRequestOptions = requestDetail.requestOptions; <span class="hljs-comment">// 设置属性 rejectUnauthorized 为 false</span> newRequestOptions.rejectUnauthorized = <span class="hljs-literal">false</span>; <span class="hljs-keyword">return</span> { requestOptions: newRequestOptions }; } }, }; </code></pre> </li> </ul> </section> </div> <div class="search-results"> <div class="has-results"> <h1 class="search-results-title"><span class='search-results-count'></span> results matching "<span class='search-query'></span>"</h1> <ul class="search-results-list"></ul> </div> <div class="no-results"> <h1 class="search-results-title">No results matching "<span class='search-query'></span>"</h1> </div> </div> </div> </div> </div> </div> <a href="./#快速开始" class="navigation navigation-next navigation-unique" aria-label="Next page: 快速开始"> <i class="fa fa-angle-right"></i> </a> </div> <script> var gitbook = gitbook || []; gitbook.push(function() { gitbook.page.hasChanged({"page":{"title":"简介","level":"1.1","depth":1,"next":{"title":"快速开始","level":"1.2","depth":1,"anchor":"#快速开始","path":"README.md","ref":"README.md#快速开始","articles":[{"title":"安装","level":"1.2.1","depth":2,"anchor":"#安装","path":"README.md","ref":"README.md#安装","articles":[]},{"title":"启动","level":"1.2.2","depth":2,"anchor":"#启动","path":"README.md","ref":"README.md#启动","articles":[]},{"title":"其他命令","level":"1.2.3","depth":2,"anchor":"#其他命令","path":"README.md","ref":"README.md#其他命令","articles":[]},{"title":"作为npm模块启动","level":"1.2.4","depth":2,"anchor":"#作为npm模块使用","path":"README.md","ref":"README.md#作为npm模块使用","articles":[]}]},"dir":"ltr"},"config":{"plugins":[],"styles":{"website":"styles/website.css","pdf":"styles/pdf.css","epub":"styles/epub.css","mobi":"styles/mobi.css","ebook":"styles/ebook.css","print":"styles/print.css"},"pluginsConfig":{"highlight":{},"search":{},"lunr":{"maxIndexSize":1000000,"ignoreSpecialCharacters":false},"sharing":{"facebook":true,"twitter":true,"google":false,"weibo":false,"instapaper":false,"vk":false,"all":["facebook","google","twitter","weibo","instapaper"]},"fontsettings":{"theme":"white","family":"sans","size":2},"theme-default":{"styles":{"website":"styles/website.css","pdf":"styles/pdf.css","epub":"styles/epub.css","mobi":"styles/mobi.css","ebook":"styles/ebook.css","print":"styles/print.css"},"showLevel":false}},"theme":"default","author":"AnyProxy","pdf":{"pageNumbers":true,"fontSize":12,"fontFamily":"Arial","paperSize":"a4","chapterMark":"pagebreak","pageBreaksBefore":"/","margin":{"right":62,"left":62,"top":56,"bottom":56}},"structure":{"langs":"LANGS.md","readme":"README.md","glossary":"GLOSSARY.md","summary":"SUMMARY.md"},"variables":{},"title":"AnyProxy","language":"cn","gitbook":"*","description":"A fully configurable http/https proxy in NodeJS"},"file":{"path":"README.md","mtime":"2018-02-05T16:06:47.879Z","type":"markdown"},"gitbook":{"version":"3.2.2","time":"2018-02-05T16:06:49.493Z"},"basePath":".","book":{"language":"cn"}}); }); </script> </div> <script src="../gitbook/gitbook.js"></script> <script src="../gitbook/theme.js"></script> <script src="../gitbook/gitbook-plugin-search/search-engine.js"></script> <script src="../gitbook/gitbook-plugin-search/search.js"></script> <script src="../gitbook/gitbook-plugin-lunr/lunr.min.js"></script> <script src="../gitbook/gitbook-plugin-lunr/search-lunr.js"></script> <script src="../gitbook/gitbook-plugin-sharing/buttons.js"></script> <script src="../gitbook/gitbook-plugin-fontsettings/fontsettings.js"></script> </body> </html>