文章目录
- 前言
- Charles代理
- HTTPS代理设置
- WKWebView的缓存机制
- 本地映射
- html 资源
- 请求
- 远端映射
- 映射到远端
- 映射到本地服务器
- Safari的调试功能
- VConsole - 推荐使用
前言
最近在排查问题时,遇到Html网页问题,总结下调试经验
Charles代理
HTTPS代理设置
关于 charles
的 https
代理设置,这里简单说明下:
- 打开 Charles,选择上侧菜单栏,选择
SSL Proxying
,安装证书到手机Mobile Device
- 根据弹框提示,打开网址下载证书,并信赖,然后配置wifi在同一网络下,设置手动代理为下图所提示的地址,例如
192.168.3.4
端口号8888
- 配置需要代理的站点
- 添加你需要抓包的站点
至此可以进行HTTPS的抓包
WKWebView的缓存机制
如果使用了 WKWebView
访问 html
资源,我们需要设置 URLRequest
实体的缓存机制为不使用缓存,这样每次才会加载 JS 等资源文件,例如如下代码
override func viewDidLoad() {
super.viewDidLoad()
let myURL = URL(string: "https://xxxxxxx/bindCard.html")
let myRequest = URLRequest(url: myURL!, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 10)
webView.load(myRequest)
}
如果不进行设置,在 Charles 中无法看到 html 相关的资源项。
本地映射
html 资源
有时候,对于 html 资源访问,如果想要修改其中的一个JS,我们可以把JS下载下来,修改之后,通过 Charles 代理来进行映射,这样达到调试的目的。
例如一个html
资源,在 charles
抓包后,有如下内容
我们想要修改这个 bind-card.js
,直接通过 URL
下载下来,修改放置到本地,然后我们需要访问这个 html 资源时,bind-card.js
文件从本地文件中去取。
- 第一种方式是直接右键该JS,然后选择
Map Local
- 第二种方式是选择
Tools->Map Local...
然后添加你的规则,这里我们使用第二种,先拷贝js的原始链接
在打开的 Map Local
窗口中,点击 add
,这里直接粘贴到 host
区域然后选择 port
,会自动填充大部分内容
这里 Port
使用 *
匹配,这里的 local Path
就是我们本地的 js 文件,这里可以先做简单的验证,例如修改加载时,弹框一个 hello world
你可以使用 alert
,这里我为了和上下文一致,使用的 layer.js
内容
layer.closeAll()
layer.open({
content: 'hello world',
skin: 'msg',
time: 2, //2秒后自动关闭
})
OK,再进行访问该网页,就可以看到 hello world
的弹框说明映射成功。
请求
对于 Post,get等请求,需要返回一个 json
数据的话,可以直接指定返回数据,同样这里我们设置 Map Local
,增加对 Post 请求路径的映射,Query
字段由于是动态参数,注意不要写死。
对于本地的路径,我们指定为返回的数据类型,如果是json类型,就指定为 .json
,内容为
{
"code": 0,
"message": "发送成功",
"data": {}
}
然后再进行请求,就可以映射为本地的结果了。
远端映射
映射到远端
如果想和 Map Local
一样映射到远端服务器,操作也是一样,不同的是远端设置需要设置连接URL
这里可以填写你需要映射的网址到 Map to
栏,如果只想测试下,你可以用 Mocky 建立一个无论怎样都返回固定数据的请求地址。
映射到本地服务器
你说你不想一个一个映射了,直接映射到我本地服务器就好了,这样方便,也是可以的,对于非前端人员,搭建本地服务器可能有点费时间,我们可以直接使用最简单的方法,使用 WebStorm
和 Charles
的配合来完成。
- OK,我们先取消所有的映射
Map Local
和Map Remote
,使用 Charles 先抓包你的请求html 资源
,右键选择Save All
,保存你的所有资源文件,这样保存才具有路径关系,使用Chrome保存的话没有path路径 - 将整个文件夹拖拽到 WebStorm 打开,然后选择
上侧菜单栏->WebStorm->Perferences
,设置端口号要小于63342
,然后勾选Can accept external connections
- 然后选择右上角的
Edit Configurations
,在弹出的窗口中设置你的Url
这里就是我们对应的 Url
地址了,当然也可以直接运行来调试。
- 然后就是配置我们的
Map Remote
了,由于我们只在本地部署了 html 的相关source和js文件,响应的 post 请求并没有部署,所以路径上要更进一级,并且Map from
的 path 需要在后面加*
,才会匹配到所有的子路径,Map to
的不需要加*
这样就可以直接映射到本地服务器了,如果有远端服务器也可以这样设置。这里只是举例说明如何映射服务器,其实本地服务器直接使用
Map Local
就可以了,如果不需要调试网页其他操作,这里不再阐述。
需要手机打开 设置 -> Safari 浏览器 -> 高级 -> Web检查器
打开,然后在 mac 端我们打开 safari,选择 上方菜单栏 -> 开发者
就可以调试我们的网页了。
也支持替换 JS ,创建本地覆盖
不过不太好用,这里不再阐述。
如果需要查看Web
的日志输出,可以使用VConsole
,开启之后,右下角会出现一个 VConsole 绿色按钮
,点击可以查看所有日志输出和元素,通过vConsole.js
重写console
方法,实现了类似于微信小程序的移动端调试效果。使用方法很简单
<script src="http://wechatfe.github.io/vconsole/lib/vconsole.min.js?v=3.2.0"></script>
<script>
// init vConsole
var vConsole = new VConsole();
console.log('Hello world');
</script>
代码中,我们可以通过注入的方式,添加这个 script
,这样子就可以随时查看日志信息。
相关注入的逻辑,可以参考类似如下方案
- 方案1
WKWebView *webview = wkWebView;
NSString *js = [WKWebViewHybridJS hybridJS];
[webview.configuration.userContentController addUserScript:[[WKUserScript alloc] initWithSource:js
injectionTime:WKUserScriptInjectionTimeAtDocumentEnd
forMainFrameOnly:NO]];
[webview.configuration.userContentController addUserScript:[[WKUserScript alloc] initWithSource:@"var vConsole = new VConsole();"
injectionTime:WKUserScriptInjectionTimeAtDocumentEnd
forMainFrameOnly:NO]];
- 方案2
[self.wkWebView evaluateJavaScript:@"navigator.userAgent" completionHandler:^(id _Nullable response, NSError *_Nullable error) {
//....
}];
具体不再阐述。