共计 2037 个字符,预计需要花费 6 分钟才能阅读完成。
原生 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 申请的解决。整体流程能够参考如下:
常见问题
通过下面的机制,既满足了离线包的资源拦挡诉求,也解决了 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 参数失落。
3.2 解决方案
神策 sdk 内反对指定 ajax 的形式上报埋点,批改上报形式为 ajax 后问题解决。
E · N · D