原生 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 丢失的问题。但是在一些场景还是存在一些问题,需要开发者进行适配。
典型的场景,是在 App 内同时集成了多个 WKWebView 容器,常见的问题现象如下:打开 mPaaS 容器后在打开三方的 WK 页面,三方 WK 页面内的 post 请求 body 参数丢失。
原因是因为 mPaaS 容器注册了全局的网络拦截,导致三方容器内的请求,也走到了 mPaas 的网络拦截,但是因为 mPaaS 容器没有启动,所以无法正常走到 mPaaS 全局拦截补全 body 的链路,导致 body 参数丢失。
在三方容器的创建的时候反注册,在销毁的时候再注册回来:
//反注册 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 }
和上面第一个 case 类似,也是在 App 内同时集成了多个 WKWebView 容器,同时三方的容器也会操作全局的网络拦截,导致 mPaaS 的网络拦截失效。
常见的问题现象如下:打开三方容器后,在打开 mPaaS 的离线包后,发现离线包会直接通过在线网络访问虚拟域名,不走离线,导致页面白屏。
参考第一个问题的解决方案,在启动 mPaaS 容器的时候,确认全局的网络拦截是可以正常生效的就可以。
有客户在容器内集成了神策的埋点 jssdk,发现埋点请求里的 body 参数丢失。
通过查看源码发现神策 jssdk 是通过 navigator.sendBeacon 发送的请求,目前 mPaas 内 hook 的 js 请求,只支持 XMLHTTPRequest,sendBeacon 还不支持,所以导致走了网络拦截后 body 参数丢失。
神策 sdk 内支持指定 ajax 的方式上报埋点,修改上报方式为 ajax 后问题解决。参考
E · N · D
前言 最近接触了微信小程序 API – wx.setScreenBrightness 、wx.ge […]...
将图片变成如下显示,借助float 和width 1111 ...
1、新建小程序项目 2、初始化:npm install,安装vant小程序框架,v […]...
1.1 WebView概述 Android WebView在Android平台上是一个特殊的View,它能用来 […]...
1.前言 项目中有些页面内容是变更比较频繁的,这些页面我们会考虑用网页来解决。 在RN项目中提供一个公用的W […]...
用小程序打造让面试官眼前一亮的简历 简历在求职中的重要性就不用我多说了,而我们程序员写的简历那肯定就要彰显出身 […]...
引言: audio是微信小程序中的音频组件,可以轻松实现小程序中播放/停止音频等自定义动作。 附上微信小程序a […]...
上一篇介绍了如何使用cocos creator开发游戏,此篇是详细介绍功能点以及如何部署打包至微信小游戏体验。 […]...
本次实验的主要目的: 1.搭建web服务,使用nfs服务共享的/data目录挂载到web站点目录上。 2.nf […]...
介绍天线的发展历史、主要参数、未来前景 天线是任何一个无线电通信系统都不可缺少的重要组成部分。各类无线电设备所 […]...
一、【问题】 目前有一字符串s = “[\’a\’, \’b\ […]...
5.2 序列化模块 将一种数据结构转换成一种特殊的序列(字符串或bytes)的过程就叫序列化。这个特殊的序 […]...
Electron-forge应用 一、 使用Electron-Forge做应用的缘由 最近遇到一个需求, […]...
4.3.2 患者主索引 EMPI 患者主索引(Enterprise Master Patient Index, […]...
1. 定义:由人工或自动化方法来执行或评估软件、以验证该软件满足规定的需求,这一个过程叫做测试。 2. 测试的 […]...
...
Powered By WordPress