技术干货 | 关于 WKWebview 网络拦截,你想知道的都在这里
原生 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
技术干货 | 关于 WKWebview 网络拦截,你想知道的都在这里的更多相关文章
- H5技术干货
H5技术干货 meta标签相关知识 H5页面窗口自动调整到设备宽度,并禁止用户缩放页面 <meta name="viewport" content="width=d ...
- 分享iOS开发常用(三方类库,工具,高仿APP,实用网站,技术干货)
一 . JSONModel (三方类库会有更新,建议大家在线下载) http://pan.baidu.com/s/1i5ybP1z 二.AFNetworkiong http://pan.baidu. ...
- 【Bugly技术干货】那些年我们用过的显示性能指标
Bugly 技术干货系列内容主要涉及移动开发方向,是由 Bugly 邀请腾讯内部各位技术大咖,通过日常工作经验的总结以及感悟撰写而成,内容均属原创,转载请标明出处. 前言: 注:Google 在自己文 ...
- 【Bugly 技术干货】Android开发必备知识:为什么说Kotlin值得一试
1.Hello, Kotlin Bugly 技术干货系列内容主要涉及移动开发方向,是由 Bugly邀请腾讯内部各位技术大咖,通过日常工作经验的总结以及感悟撰写而成,内容均属原创,转载请标明出处. 1. ...
- 技术干货:实时视频直播首屏耗时400ms内的优化实践
本文由“逆流的鱼yuiop”原创分享于“何俊林”公众号,感谢作者的无私分享. 1.引言 直播行业的竞争越来越激烈,进过2018年这波洗牌后,已经度过了蛮荒暴力期,剩下的都是在不断追求体验.最近正好在做 ...
- 2017-2018-2 20155303『网络对抗技术』Exp7:网络欺诈防范
2017-2018-2 『网络对抗技术』Exp7:网络欺诈防范 --------CONTENTS-------- 一.原理与实践说明 1.实践目标 2.实践内容概述 3.基础问题回答 二.实践过程记录 ...
- 20155308『网络对抗技术』Exp7:网络欺诈防范
20155308『网络对抗技术』Exp7:网络欺诈防范 原理与实践说明 1.实践目标 本实践的目标是:理解常用网络欺诈背后的原理,以提高防范意识,并提出具体防范方法. 2.实践内容概述 简单应用SET ...
- 2018-2019-2 20165209 《网络对抗技术》Exp7: 网络欺诈防范
2018-2019-2 20165209 <网络对抗技术>Exp7: 网络欺诈防范 1 基础问题回答和实验内容 1.1基础问题回答 (1)通常在什么场景下容易受到DNS spoof攻击. ...
- 基于puppeteer的网络拦截工具flyover
为什么需要网络拦截工具 通常我们会遇到这样的场景: 线上一个图片有异常,线下修正之后需要发布之前进行测试,有些情况下,QA同学有直接在线上环境测试的需求,只是链接本地资源,通常在windows下有一个 ...
随机推荐
- 1.设置和验证MySQL数据库的隔离级别
登录数据库 mysql -u root - p 新建用户,各启动一个事物,用于同时操作数据库表中数据 create user tom identified by 'tom'; 然后同时再用该用户启动M ...
- 嗝,我饱了——IDEA食用指南
1 概述 IDEA全称IntelliJ IDEA,主要用于Java开发的IDE,代码自动提示,重构,JUnit,代码分析等的功能非常牛逼,这篇文章首先介绍目前为止IDEA最新版本的特性,然后从UI,常 ...
- Salesforce学习之路(五)role hierarchy & sharing
1. Role Hierarchy 在私有或者混合模型中,如果在organization-wide defaults设置某个对象为Private,那么对象的记录只有拥有者可以查看.但是,role hi ...
- 【SpringBoot源码分析】-Bean的加载过程
-- 以下内容均基于2.1.8.RELEASE版本 在<SpringBoot启动过程的分析>系列文章中简要的对SpringBoot整体的启动流程作了梳理,但并未针对诸多细节进行分析.前面的 ...
- docker搭建简单mysql主从
关于MySQL主从模式,如果我们直接在本机上搭建的话,是没法搭建的,只能借助于虚拟机,但有的时候我们又需要搭建一个主从集群,以便于进行一些功能性的测试.这个时候我们就可以尝试使用docker,借助于d ...
- VScode+Sublime安装与汉化
两大常用编辑器安装与汉化 想敲代码?工欲善其事,必先利其器,先安装编写代码所需要的工具吧.本期的主角是VScode与Sublime,这是两款比较热门的代码编辑器. 目录: VScode安装与汉化 Su ...
- Win64 驱动内核编程-30.枚举与删除线程回调
枚举与删除线程回调 进程回调可以监视进程的创建和退出,这个在前面的章节已经总结过了.某些游戏保护的驱动喜欢用这个函数来监视有没有黑名单中的程序运行,如果运行则阻止运行或者把游戏退出.而线程回调则通常用 ...
- HR:“最喜欢阿里出来的程序员了,技术又好又耐艹!” 我:???
面试造火箭,进厂拧螺丝?真的是这样吗? 缘起 估计不少同学都是被标题吸引进来的.事先声明,这句话不是我虚构的,而是我实实在在从同事的口中听到的,而且还不止一次. 当时的场景就是很正常的交谈,别人也并没 ...
- spring-boot-maven-plugin not found的解决方案
spring-boot-maven-plugin not found 在maven测试的生命周期都没有错,但是就是爆红 参考了很多的链接,没有成功解决,最后得到真正有帮助的方法,添加springboo ...
- Pulsar部署和实践(一)
前言 本地Docker部署Pulsar消息代理实现消息发布和消息订阅 介绍 相关概念,后面有时间再花时间整理下. 实践步骤 1.使用dokcer本地部署pulsar docker run -it \ ...