摘要:下面介绍在微信开发调试方面的应用。微信网页开发中,由于有接口安全域名和授权域名等的限制,导致部分功能需要部署到线上才能测试。设置代理服务器打开微信开发者工具,设置代理设置选择手动设置代理。
Fiddler是一个非常强大的代理工具,可以让你的前端开发调试更加方便。下面介绍在微信开发调试方面的应用。
微信网页开发中,由于有js接口安全域名和授权域名等的限制,导致部分功能需要部署到线上才能测试。通过代理可以实现本地调试网站的所有功能。
配置代理规则全站转发可以这样设置:Tools -> HOSTS
图片中表示your.domain.com的请求全部转发到127.0.0.1:8000。第二个参数的限制是:不能加协议、路径或参数。
如果你的网站域名和接口域名是同一个,那就不能使用全站转发了,需要html、css、js、websocket请求转发到本地,接口调用请求则直接发送到远程服务器。
可以使用自定义规则实现
上面图片中的正则表达式和目标地址如下:
regex:^http://your.domain.com(?!/api|/swagger|/webjars|/configuration/ui)(.*) http://localhost:8000$1
本条规则表示:将your.domain.com下的http请求转发到localhost:8000,其中/api、/swagger、/webjars、configuration/ui开头的路径不转发。
目标地址表达式中的$1代表原始请求URL域名后面的字符串,包括path和search。
设置代理服务器打开微信开发者工具,设置 -> 代理设置 -> 选择手动设置代理。
Fiddler默认运行在127.0.0.1:8888。
在真机上测试本地微信网页项目的步骤如下:
手机和电脑连接同一个局域网。
设置Fiddler允许远程连接,Tools -> Options -> Connections -> 勾选Allow remote computers to connect。
查看电脑在局域网中的IP地址,命令行输入ipconfig(windows)。
手机网络配置代理服务器。
到这里,本篇文章的主要内容就结束了,如果你想了解更多关于Fiddler和代理工具的使用,可以参考我同事的文章代理工具Fiddler -调试与替换接口状态,
代理工具做微信项目的调试配置。
如果你想了解使用nodejs如何实现上述以及更多自定义的功能,敬请往下阅读。
下文中,client表示客户端(浏览器),proxy表示代理服务器,server表示目标服务器
HTTP实现HTTP代理服务器是非常简单的,因为HTTP为明文传输,所以proxy只需要解析client的HTTP报文,再向server发送相同的请求,server响应时,proxy将HTTP响应状态,响应首部字段和响应主体返回给client即可。
这里可以使用nodejs的http模块实现
const http = require("http"); const { URL } = require("url"); let server = http.createServer((req, res) => { let { pathname, search, hostname, port } = new URL(req.url); console.log("http ", req.url); // 后端api调用请求直接发送给远程服务器,除此之外的HTTP请求发送给本地运行的端口 if (!pathname.startsWith("/api")) { hostname = "localhost"; port = 8000; // 项目运行的端口 } req.pipe(http.request({ hostname, port, path: `${pathname}${search}`, method: req.method, headers: req.headers }, (response) => { res.writeHead(response.statusCode, response.statusMessage, response.headers); response.pipe(res); })); }); server.listen(8888);HTTPS
只有HTTP代理服务器是不够的,因为不管是微信开发工具,还是浏览器,都有可能发送HTTPS请求。比如微信开发者工具的登录和域名校验就是使用的HTTPS与微信服务器通信的,如果不代理这部分流量是无法正常运行微信开发者工具的。
HTTPS因为报文加密的原因,proxy不能解析报文后伪装client发送请求。最常见的解决方案是web隧道,proxy建立和client、server的TCP连接,之后盲转发两端的数据。
建立web隧道的方式之一是使用HTTP的CONNECT方法,实际上客户端(浏览器)设置了代理服务器后,client发出的HTTPS请求是不同的,它首先会使用CONNECT方法发送HTTP请求,请求proxy建立连接,这是proxy能代理HTTPS的关键。
client请求proxy与server建立TCP连接的HTTP报文如下:
CONNECT your.domain:443 HTTP/1.1 Host: your.domain:443 Connection: keep-alive User-Agent: M....
proxy在与server建立TCP连接后,按照约定,需要200 Connection Established响应,响应首部字段可自定义:
HTTP/1.1 200 Connection Established Connection: close
所以http服务器就可以代理https请求。实际上,按照上面的原理http服务器能够代理很多其他协议的流量。
https代理服务器需要使用http和net模块,对上面的http代理的代码扩展即可
server.on("connect", (req, clientSocket) => { let { port, hostname } = new URL(`http://${req.url}`); console.log("https", req.url); let serverSocket = net.connect(port || 80, hostname, () => { clientSocket.write( `HTTP/1.1 200 Connection Established Connection: close ` ); clientSocket.pipe(serverSocket); serverSocket.pipe(clientSocket); }); });
从实现方式可以看出来,这种代理服务器是无法正常获取和更改通信双方的数据的。如果要实现能监听和更改通信数据的HTTPS代理服务器,可以使用自签名证书实现,这里不做探究。
websocket本地开发的项目往往有热更新功能,而热更新的通信依靠websocket,所以websocket代理也是必不可少的。websocket的连接也是用HTTP建立起来的。
如果根据我们之前了解的websocket知识,client会向服务器发送协议升级请求(请求报文中包含特殊的请求首部字段),服务器响应101 Switching Protocols,之后的数据则转为websocket协议发送。根据以上流程,同样只需要对http服务器代码扩充即可,我们很容易写出如下代码:
server.on("upgrade", (req, clientSocket) => { let { pathname, search, hostname, port } = new URL(req.url); console.log("websocket", req.url); let request = http.request({ pathname: "localhost", port: 8000, // 项目运行的端口 method: req.method, headers: req.headers }); req.pipe(request); request.on("upgrade", (response, serverSocket) => { let resStr = "HTTP/1.1 101 Switching Protocols "; for (let [key, value] of Object.entries(response.headers)) { resStr += `${key}: ${value} `; } resStr += " "; clientSocket.write(resStr); clientSocket.pipe(serverSocket); serverSocket.pipe(clientSocket); }); }); server.listen(8888)
上面的写法实际上是反向代理服务器的写法。即,浏览器直接建立到ws://localhost:8888的请求,该代理服务器是能够将请求转发到8000端口的,但当浏览器设置了代理服务器后,发送websocket请求和没设置前是不同的,它同样会先向proxy请求建立连接,所以代理websocket请求和代理https请求代码是一样的,我们在connect事件中做好区分即可。
server.on("connect", (req, clientSocket) => { let { port, hostname } = new URL(`http://${req.url}`); console.log("https", req.url); // websocket请求发送到本地8000端口 if (req.url === "your.domain.com:80") { port = 8000; // 项目运行的端口 hostname = "localhost"; } let serverSocket = net.connect(port || 80, hostname, () => { clientSocket.write( `HTTP/1.1 200 Connection Established Connection: close ` ); console.log(req.url, "connect"); clientSocket.pipe(serverSocket); serverSocket.pipe(clientSocket); }); });
经过以上三步,一个带有完整功能的代理服务器就写好了,想要实现自定义功能,无非是在请求报文识别和server响应报文篡改上做文章,尽情发挥你的创造力吧。
原文链接
【作者简介】:叶茂,芦苇科技web前端开发工程师,代表作品:口红挑战网红小游戏、服务端渲染官网、微信小程序粒子系统。擅长网站建设、公众号开发、微信小程序开发、小游戏、公众号开发,专注于前端领域框架、交互设计、图像绘制、数据分析等研究。 一起并肩作战: yemao@talkmoney.cn 访问 www.talkmoney.cn 了解更多
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/106777.html
摘要:我个人比较推荐的方法是或者安卓手机的这种方式,比较简单方便快捷,然后根据具体的环境再选择更为合适的调试方法。 本文首次发表于本人的个人博客:http://cherryblog.site/ ,欢迎大家到我的博客查看更多文章~ 前言 在开发中前端免不了要进行移动端的开发,然而在电脑上看的样式和手机上还是有一定的差距的,因为手机上有顶部的状态栏和底部的菜单栏,特别是在qq内置浏览器中打开,差...
摘要:直到今天,突然看到一个有意思的微信小游戏。后来试了几次之后才发现,这个小游戏比较刁,不仅做了微信的登录授权,而且做了手机端访问的判断,更甚至竟然用的还是协议的网页。调用的目标发生了异常。 记一次使用Fiddler抓包工具抓取Https协议数据的踩坑过程 前言 记得从刚入门前端第一天开始,当时的师傅就跟我介绍了一个可以抓取一些必须要在微信浏览器打开的链接的工具Fiddler,主要用来抓取...
摘要:如何使用开发者中心进行在线调试如果你已经使用了开发者中心部署应用上云,那么,可以非常荣幸的告诉你,看完下面的步骤,只需几秒钟的配置,就可以解救你于水火之中。此过程也可以用于日常开发过程中的在线定位问题,面对众多的微服务,无需再烦恼了。 现在,大家开始越来越多的谈论到高可用架构的互联网应用。什么是高可用?高可用HA(High Availability)是分布式系统架构设计中必须考虑的因素...
摘要:如何使用开发者中心进行在线调试如果你已经使用了开发者中心部署应用上云,那么,可以非常荣幸的告诉你,看完下面的步骤,只需几秒钟的配置,就可以解救你于水火之中。此过程也可以用于日常开发过程中的在线定位问题,面对众多的微服务,无需再烦恼了。 现在,大家开始越来越多的谈论到高可用架构的互联网应用。什么是高可用?高可用HA(High Availability)是分布式系统架构设计中必须考虑的因素...
阅读 2177·2023-04-25 19:06
阅读 1374·2021-11-17 09:33
阅读 1766·2019-08-30 15:53
阅读 2581·2019-08-30 14:20
阅读 3540·2019-08-29 12:58
阅读 3533·2019-08-26 13:27
阅读 501·2019-08-26 12:23
阅读 484·2019-08-26 12:22