WKWebview在NSURLProtocol中body丢失问题
2020-03-16 本文已影响0人
Auditore
背景说明
之所以想hook XMLHTTPRequest是因为NSURLProtocol导流WKWebview有body丢失问题。要解决这个问题,目前一个思路,通过注入JS代码的方式来解决这个问题,在NSURLProtocol的didReceiveData函数中,我们可以第一时间接收到请求返回的HTML数据,然后我们把hook XMLHTTPRequest的send方法和open的JS函数插入到HTML之中,然后再返回给系统。
在hook代码里面要重组url和body参数并且加上标识位,然后重新发起get请求,然后这时候我们的NSURLProtocol会再次捕获这个重新发起的get请求,根据我们请求中的标记,辨别出是我们重组过的请求,将请求中的参数取出来(我们把body存放在文件里,做好标识,便于一一对应request,方便读取),再次拼接以后塞入body发起post请求。
1.Hook XMLHTTPRequest
我打算分成两步来进行,第一部分已经完成,第二部分还在进行中。
1.1 hook XMLHTTPRequest发起的请求
XMLHTTPRequest的hook,参考https://github.com/wendux/Ajax-hook 使用起来很简单,把hookAjax函数插入script标签就可以了。如下范例,
<script src="https://unpkg.com/ajax-hook/dist/ajaxhook.min.js"></script>///这行插入到HTML文件的head标签内
///如下内容插入到body标签内
<script>
hookAjax(
// hook functions and callbacks of XMLHttpRequest object
{
onreadystatechange: function (xhr) {
console.log("onreadystatechange called: %O", xhr)
//return true
},
onload: function (xhr) {
console.log("onload called: %O", xhr)
xhr.responseText = "hook" + xhr.responseText;
//return true;
},
open: function (arg, xhr) {
console.log("open called: method:%s,url:%s,async:%s", arg[0], arg[1], arg[2], xhr)
arg[1] += "?hook_tag=1";
//统一添加请求头
},
send: function (arg, xhr) {
console.log("send called: %O", arg[0])
xhr.setRequestHeader("_custom_header_", "ajaxhook")
},
setRequestHeader: function (arg, xhr) {
console.log("setRequestHeader called!", arg)
},
// hook attributes of XMLHttpRequest object
timeout: {
setter: function (v, xhr) {
//timeout shouldn't exceed 10s
return Math.max(v, 1000);
}
}
}
);
$.get().done(function (d) {
console.log(d.substr(0, 30) + "...")
//use original XMLHttpRequest
console.log("unhook")
unHookAjax()
$.get().done(function (d) {
console.log(d.substr(0, 10))
})
})
</script>
通过控制台的log,验证后,可以拦截到请求。
1.2 将hook代码接入NSURLProtocol
时间关系,这部分还在验证。这是下个阶段的任务。
2.另一种思路
XMLHTTPRequest是否有设置proxy的方式?如果可行的话,是不是就一步登天了?可惜,并不能,不过,有个老哥提出了另一种方式,https://juejin.im/post/5db85842f265da4d1f51bbda ,这种方式也算是hook的变种。
这种方式待验证.