简介:mPaas-WKWebview网络拦挡常见问题

1. 背景

原生WKWebView在独立于app过程之外的过程中执行网络申请,申请数据不通过主过程,因而在 WKWebView 上间接应用NSURLProtocol 是无奈拦挡申请的。然而因为mPaas的离线包机制强依赖网络拦挡,所以基于此,mPaas利用了WKWebview的暗藏api,去注册拦挡网络申请去满足离线包的业务场景需要,参考代码如下:

[WKBrowsingContextController registerSchemeForCustomProtocol:@"https"]

然而因为出于性能的起因,WK的网络申请在给主过程传递数据的时候会把申请的body去掉,导致拦挡后申请的body参数失落。在离线包场景,因为页面的资源不须要body数据,所以离线包能够失常应用不受影响。然而在H5页面内的其余post申请会失落data参数。为了解决post参数失落的问题,mPaas通过在js注入代码,hook了js上下文里的XMLHTTPRequest对象解决。通过在JS层把办法内容组装好,而后通过WKWebView的messageHandler机制把内容传到主过程,把对应HTTPBody而后存起来,随后告诉JS端持续这个申请,网络申请到主过程后,在将post申请对应的HttpBody增加上,这样就实现了一次post申请的解决。整体流程能够参考之前崔同学的分享流程图如下:


图1

2. 遇到的问题

通过下面的机制,既满足了离线包的资源拦挡诉求,也解决了post申请body失落的问题。然而在一些场景还是存在一些问题,须要开发者进行适配。

2.1. mPaas容器和三方容器混用导致三方容器申请body失落

2.1.1. 问题场景

典型的场景,是在App内同时集成了多个wkwebview容器,常见的问题景象如下:关上mPaas容器后在关上三方的WK页面,三方WK页面内的post申请body参数失落。起因是因为mPaas容器注册了全局的网络拦挡,导致三方容器内的申请,也走到了mPaas的网络拦挡,然而因为mPaas容器没有启动,所以无奈失常走到mPaas全局拦挡补全body的链路,导致body参数失落。

2.1.2. 解决方案

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

j//反注册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    }

2.2. mPaas容器关上离线包后间接拜访虚构域名导致白屏

2.2.1. 问题场景

和下面第一个case相似,也是在App内同时集成了多个wkwebview容器,同时三方的容器也会操作全局的网络拦挡,导致mPaas的网络拦挡生效。常见的问题景象如下:关上三方容器后,在关上mPaas的离线包后,发现离线包会间接通过在线网络拜访虚构域名,不走离线,导致页面白屏。

2.2.1. 解决方案

参考第一个问题的解决方案,在启动mPaas容器的时候,确认全局的网络拦挡是能够失常失效的就能够。

2.3. mPaas容器内sendBeacn申请body失落

2.3.1. 问题场景

有客户在容器内集成了神策的埋点jssdk,发现埋点申请里的body参数失落。通过查看源码发现神策jssdk是通过navigator.sendBeacon发送的申请,目前mPaas内hook的js申请,只反对XMLHTTPRequest,sendBeacon还不反对,所以导致走了网络拦挡后body参数失落。


图2

2.3.1. 解决方案

神策sdk内反对指定ajax的形式上报埋点,批改上报形式为ajax后问题解决。可参考文后材料[1]理解详情。


图3

[1]JavaScript SDK 应用阐明:https://www.sensorsdata.cn/2.0/manual/js\_sdk.html

咱们是阿里云智能寰球技术服务-SRE团队,咱们致力成为一个以技术为根底、面向服务、保障业务零碎高可用的工程师团队;提供业余、体系化的SRE服务,帮忙广大客户更好地应用云、基于云构建更加稳固牢靠的业务零碎,晋升业务稳定性。咱们冀望可能分享更多帮忙企业客户上云、用好云,让客户云上业务运行更加稳固牢靠的技术,您可用钉钉扫描下方二维码,退出阿里云SRE技术学院钉钉圈子,和更多云上人交换对于云平台的那些事。

版权申明:本文内容由阿里云实名注册用户自发奉献,版权归原作者所有,阿里云开发者社区不领有其著作权,亦不承当相应法律责任。具体规定请查看《阿里云开发者社区用户服务协定》和《阿里云开发者社区知识产权爱护指引》。如果您发现本社区中有涉嫌剽窃的内容,填写侵权投诉表单进行举报,一经查实,本社区将立即删除涉嫌侵权内容。