首页 热点资讯 义务教育 高等教育 出国留学 考研考公
您的当前位置:首页正文

WKWebview在NSURLProtocol中body丢失问题

2024-12-20 来源:化拓教育网

背景说明

之所以想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发起的请求

<script 
///如下内容插入到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.另一种思路

显示全文