原生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
通过上面的机制,既满足了离线包的资源拦截诉求,也解决了post请求body丢失的问题。但是在一些场景还是存在一些问题,需要开发者进行适配。
2.1. mPaas容器和三方容器混用导致三方容器请求body丢失典型的场景,是在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容器打开离线包后直接访问虚拟域名导致白屏
和上面第一个case类似,也是在App内同时集成了多个wkwebview容器,同时三方的容器也会操作全局的网络拦截,导致mPaas的网络拦截失效。常见的问题现象如下:打开三方容器后,在打开mPaas的离线包后,发现离线包会直接通过在线网络访问虚拟域名,不走离线,导致页面白屏。
2.2.1. 解决方案参考第一个问题的解决方案,在启动mPaas容器的时候,确认全局的网络拦截是可以正常生效的就可以。
2.3. mPaas容器内sendBeacn请求body丢失有客户在容器内集成了神策的埋点jssdk,发现埋点请求里的body参数丢失。通过查看源码发现神策jssdk是通过navigator.sendBeacon发送的请求,目前mPaas内hook的js请求,只支持XMLHTTPRequest,sendBeacon还不支持,所以导致走了网络拦截后body参数丢失。
图2
神策sdk内支持指定ajax的方式上报埋点,修改上报方式为ajax后问题解决。可参考文后资料[1]了解详情。
图3
[1]JavaScript SDK 使用说明:https://www.sensorsdata.cn/2.0/manual/js_sdk.html
我们是阿里云智能全球技术服务-SRE团队,我们致力成为一个以技术为基础、面向服务、保障业务系统高可用的工程师团队;提供专业、体系化的SRE服务,帮助广大客户更好地使用云、基于云构建更加稳定可靠的业务系统,提升业务稳定性。我们期望能够分享更多帮助企业客户上云、用好云,让客户云上业务运行更加稳定可靠的技术,您可用钉钉扫描下方二维码,加入阿里云SRE技术学院钉钉圈子,和更多云上人交流关于云平台的那些事。
哪里有试用 云服务器 ?现在大部分 云服务器 厂商都提供云服务的试用服务,不过...
说起共享单车,我们会想到遍布大街小巷的摩拜、OFO等,摩拜们高举高打,攻城略地...
来源 | 阿里飞天CIO学堂微信公众号 在门锁行业内,王力百万挑战开锁王的故事一直...
设置FunctionGraph函数的环境变量,无需对代码进行任何更改,可以将设置动态参数...
点击查看更多ICBU风控算法相关内容 ICBU风控算法专题 ,【订阅专题】第一时间get...
2020年12月30日,中国联通“联通链”发布会暨中国联通(海南)创新研究院揭牌仪...
本文转载自微信公众号「码农读书」,作者码农读书 。转载本文请联系码农读书公众...
公司网站 域名 空间多少钱?公司搭 建网站 缺少不了域名和空间,具体需要多少钱...
基本概念 从数据存储来看,数组存储方式和树的存储方式可以相互转换,即数组可以...
近年来,互联网经济、数字经济的快速发展,人工智能、物联网、云计算等产业的飞...