当前位置:主页 > 查看内容

技术干货 | 关于 WKWebview 网络拦截,你想知道的都在这里

发布时间:2021-05-28 00:00| 位朋友查看

简介:原生 WKWebView 在独立于 app 进程之外的进程中执行网络请求 请求数据不经过主进程 因此在 WKWebView 上直接使用 NSURLProtocol 是无法拦截请求的。 但是由于 mPaas 的离线包机制强依赖网络拦截 所以基于此 mPaaS 利用了 WKWebview 的隐藏 api 去注册拦截网……

2019产品成绩单2.png

封面图0528.jpg

原生 WKWebView 在独立于 app 进程之外的进程中执行网络请求 请求数据不经过主进程 因此在 WKWebView 上直接使用 NSURLProtocol 是无法拦截请求的。


但是由于 mPaas 的离线包机制强依赖网络拦截 所以基于此 mPaaS 利用了 WKWebview 的隐藏 api 去注册拦截网络请求去满足离线包的业务场景需求 参考代码如下

[WKBrowsingContextController registerSchemeForCustomProtocol: https ]

但是因为出于性能的原因 WKWebView 的网络请求在给主进程传递数据的时候会把请求的 body 去掉 导致拦截后请求的 body 参数丢失。


在离线包场景 由于页面的资源不需要 body 数据 所以离线包可以正常使用不受影响。但是在 H5 页面内的其他 post 请求会丢失 data 参数。


为了解决 post 参数丢失的问题 mPaas 通过在 js 注入代码 hook 了 js 上下文里的 XMLHTTPRequest 对象解决。


通过在 JS 层把方法内容组装好 然后通过 WKWebView 的 messageHandler 机制把内容传到主进程 把对应 HTTPBody 然后存起来 随后通知 JS 端继续这个请求 网络请求到主进程后 在将 post 请求对应的 HttpBody 添加上 这样就完成了一次 post 请求的处理。整体流程可以参考如下

1.png


常见问题

通过上面的机制 既满足了离线包的资源拦截诉求 也解决了 post 请求 body 丢失的问题。但是在一些场景还是存在一些问题 需要开发者进行适配。


mPaaS 容器和三方容器混用导致三方容器请求 body 丢失1.1 问题场景

典型的场景 是在 App 内同时集成了多个 WKWebView 容器 常见的问题现象如下 打开 mPaaS 容器后在打开三方的 WK 页面 三方 WK 页面内的 post 请求 body 参数丢失。


原因是因为 mPaaS 容器注册了全局的网络拦截 导致三方容器内的请求 也走到了 mPaas 的网络拦截 但是因为 mPaaS 容器没有启动 所以无法正常走到 mPaaS 全局拦截补全 body 的链路 导致 body 参数丢失。


1.2 解决方案

在三方容器的创建的时候反注册 在销毁的时候再注册回来

//反注册
Class cls NSClassFromString( WKBrowsingContextController 
 SEL sel NSSelectorFromString([NSString stringWithFormat: unregisterSchemeForCustomProtocol: 
 if ([(id)cls respondsToSelector:sel]) {
 [(id)cls performSelector:sel withObject: http 
 [(id)cls performSelector:sel withObject: https 
 //注册
 Class cls NSClassFromString( WKBrowsingContextController 
 SEL sel NSSelectorFromString([NSString stringWithFormat: registerSchemeForCustomProtocol: 
 if ([(id)cls respondsToSelector:sel]) {
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored -Warc-performSelector-leaks 
 [(id)cls performSelector:sel withObject: http 
 [(id)cls performSelector:sel withObject: https 
 #pragma
 }


mPaaS 容器打开离线包后直接访问虚拟域名导致白屏2.1 问题场景

和上面第一个 case 类似 也是在 App 内同时集成了多个 WKWebView 容器 同时三方的容器也会操作全局的网络拦截 导致 mPaaS 的网络拦截失效。


常见的问题现象如下 打开三方容器后 在打开 mPaaS 的离线包后 发现离线包会直接通过在线网络访问虚拟域名 不走离线 导致页面白屏。


2.2 解决方案

参考第一个问题的解决方案 在启动 mPaaS 容器的时候 确认全局的网络拦截是可以正常生效的就可以。


mPaaS 容器内 sendBeacn 请求 body 丢失3.1 问题场景

有客户在容器内集成了神策的埋点 jssdk 发现埋点请求里的 body 参数丢失。


通过查看源码发现神策 jssdk 是通过 navigator.sendBeacon 发送的请求 目前 mPaas 内 hook 的 js 请求 只支持 XMLHTTPRequest sendBeacon 还不支持 所以导致走了网络拦截后 body 参数丢失。

2.png


3.2 解决方案

神策 sdk 内支持指定 ajax 的方式上报埋点 修改上报方式为 ajax 后问题解决。参考

3.png


E · N?· D

作者介绍(荣阳).png


本文转自网络,原文链接:https://developer.aliyun.com/article/784361
本站部分内容转载于网络,版权归原作者所有,转载之目的在于传播更多优秀技术内容,如有侵权请联系QQ/微信:153890879删除,谢谢!
上一篇:微服务架构下日志采集运维管理分析 下一篇:没有了

推荐图文

  • 周排行
  • 月排行
  • 总排行

随机推荐