WKWebView拦截实现探讨
背景
苹果更新邮件
Updating Apps that Use Web Views December 23, 2019 If your app still embeds web content using the deprecappreciateated UIWebView API, we strongly encourage you to update to WKWebVie长沙市天气w as soon as possible for improved security and reliability. WKWebView ensures that compromiapplesedios下载 web content doesn’t aff辰时是几点到几点ect the rest of an app by limiting web pro陈涉世家翻译及原文cessing编辑器和编译器的区别 to the app’s web view. And it’s supported in iOSappearance and macOS, and by Mac Caios模拟器talyst. The App Store will no longer accept new apps using UIWebView as of April 2020 and a环路复杂度pp updates using UIWebView as of December 2020.
项目中UIWebView使用场景
- jssdk使用h5调用方法后JSSDK新建iframe节点,webview监听事件进行处理
- 签名授权webview拦截appreciate带sign_suffix后缀的请求复杂度后,客户端去请求授权
- 加载离线资源使用系统的apiapple NSURLProtocol在上层拦截webview中的离线请求焯是什么梗,客户端进行离线处理
iOS拦截url加载离线实现流程图
iOS端加载离线就是如何将离线url拦截并返回数据的过程
实现
NSURLProtocol
Don’t instantiate an NS仓鼠饲养八大禁忌URLProtocol subclass directl编辑器y. Instead, create subclasses for any custom protocols or URL scheme编辑器英文s that your app supports. When a downloaappointmentd starts, the system creates the appropriate protocol object to handle the corresponding URL request. You define长生十万年 your protocol class and call the registerC圈复杂度lass: class method during your apios下载p’s launch tim编辑器e so that the system is aware of your protocol.
基本使用
- canInitWithRequest:系统询问是否拦截request,通常是匹配url是否满足特定要求。比编辑器小说如标复杂度怎么计算的准版中的几种拦截方式:
-
- 网页静态资源拦截规则:h陈思思ost以zuolin.com结尾,path以.js .css .png .gif .webp结尾
- 本地图片拦截规则:scheme == zl,host == resourceid
-
- 网络图片拦截规则:host以zuolin.com结尾,path包含/image
- 离线包拦截规则:ho环形复杂度st以zuolin.com结尾,path包含/nar
- initWithRequest:自定义复杂度怎么计算的urlProtocol的初始化方法
- startLios系统oading:request开始加载,在环路复杂度这里处理缓存逻辑,如果有缓存返回data,没有缓存由native发起请求返回data
- stopLoading:request结束加载
缺陷
- 不像UIWebView的加载是appearance在app的进程,WKappleWebView是独立的进程,如果不手动注册scheme,app根本收不到urlProtocol的相应方法
- 如果手动注册scheme后,wkWebView通过IPC与app所在进程通信,由于性能问题,会丢弃request中的body及approachbodyStream字段,H5中所有的post请求会失效
workaround
- H5侧将post请求参数放在header中,urlProtocol拦截后取header中的参数拼接在body中,由客户端完成请求
- wkWebView注入js hook ajaxapplication post请求后由客户端完成请求
-
- ①中记录xhrid
- ②中根据xhrid找到对应的xhr
WKUrlSchemeHandler
A protocol for loading r陈思思esources wit编辑器和编译器的区别h URL schemes that WebKit doesn’t know how to handle.iOS11后开放的API,只拦截自定义scheme的url,常用的http、https链接拦截不了
基本使用
- cuapple苹果官网stomHandler:实现WKUrlSchemeHandler的实例,设置为配置项后,wkWebView中加载custo编辑器软件mScheme的request会走customHandler的处理
let config = WKWebViewConfiguration()
config.setURLSchemeHandler(HttpProxyHandler(), forURLScheme: "customScheme")
- startUrlSchemeTask:开始加载自定义sc长生十万年heme的appointmentrequest,在这里处理缓存逻辑,有缓存返回data,无缓存native请求后返回data
- stopUrlSchemeTask:结束加载request
H5支撑
需要H5侧统一所有离圈复杂度线资源的url,如果客户端使用的WKWebView(客户端在UA里面加标识),将url的scheme改为协定的customScheme,交陈思思由客户端处理
WKURLSchemeHand编辑器小说ler拦截方案评估
拦截流程
- 替换根节点(html)的scheme为协定的customScheme,交由客户端处理
- 后续所有节点的request算法复杂度由于同源(相对路径、相对协议)application,也会带上协定的customScheme,也会被客户端拦截处appearance理
缺陷
- x编辑器哪个好用hr陈涉世家翻译及原文的post请求被拦截后,iOS13以下的设备request会丢失body,客户端拦截请求后反而会失败
解决方案
- HTML里面的资源文件全部用://user/a.png这种相对的写法。这样 ht编辑器tp 和 自定义协议复杂度都可以用
- HTML里iOS面复杂度的xhr post请求使用绝对路径,客编辑器户端不拦截处理,修改后端的 Response 头,使用 Cross-Origin Resource Sharing (CORS) 技术
代理XHR拦截方案评估
实现流程
通过代理xhr对象监听h5里面xhr的post请求,监听到的请求交由客户端去处理,圈复杂度代理xhr对象拿到数据后会调用xhr的相应事件完成请求
实现难点
- 代理xhr对象的编写(网上参考编辑器ajaxhook.js)
- 代理xhr对象数据多样性的传递及H5侧的解析
h5的xhr请求是否只能解析conteios模拟器nt-type:application/json的数据?
- 代理xhr对象与nativeios14.4.1更新了什么的交互
1、2由h5端实现,3由客户端实现
Cookie的使用及问题
使用
- UIWebView
-
- 客户端设置
由于uiwebview中的所有请求都会带上NSHttpCookieStorage中的cookies,所以可以使用NSHttpCookieStorage直接设置cookie
-
- 后台设置
接口返回的response header中返回set-cookie,系统会自动同步进NSHttpCookieStorage
- WKWebView
wkwebview有自己独立的进apple程,请求时不会使用NSHttpCookieStorage中的cookie,并且wkwebview同步cookie进NSHttpCookieStorage的时机有延迟。
wkwebview中的cookie注入编辑器有三种方式:
-
-
- NSURLRequest header中手动加入cookie
- WKWebView中通过js注入cookie
-
-
-
- iOS11以后,通过WKWebSiteStore.httpCookieStorage设置cookie,用法和NSHttpCookieStorage类似
-
-
项目中WKWebView中cookie的管理和使用
-
- 用户登录后后台返回算法复杂度cookie,wkwebview创建后第一次请求时,会在request中加入cookie
- decidePolicyForAction:方法中每次跳转页面时会同步cookie
-
-
- 同步NSHttpCookieStorage中的cookie
- 同步登录时后台返回的cookie
-
-
- decidePolicyForResponse:方法中将response header里面的coappstoreokie时间复杂度同步至NSHttpCooappreciatekieStorage,为后续页面cookie的同步作准备
问题
A页appointment面中调用了某个接口CSS,后台设置了cookieA,跳转B页面时拿不到cookieA
- 项目中使用
现在用户登录后会返回相应的cookie,因ios模拟器为某些环境未如期返回cookie,造成H5应用首页中调用logonBySignature设置cookie后,后续跳转到的页面拿不到cookie,陈思思引起调用异常。
wkwebview的cookie只能客户端手动注入,其相应的代理方法也只能监听主页面(mainFrame)的回调,业务接口中设置的cookie拿不到。此问题需前后端进行优化。
场景:电商跳同一订单接口报未授权
-
- 旧的逻辑
-
- 新逻辑(改后逻辑)
本质是后台set-cookie,cookie跨域,在客户端不干预的前提下,跨域的页面拿不到cookie,所以应该尽量避免302塞cookie的场景
- 第三方网页
-
- oauth
针对oauth授权的网页,wkwebview可在decidePolicyForResponse代理方法中拿到response,从而获取cookie,注入后实现后续页面跳转
-
- SSO
SSO授权的网页,一般token的产生在一个比appstore较靠前的时间点,可以提前注入
方案确定
WKUrlSchemeHandler
针对post请求body丢失的缺陷,H5端由于业务复杂度无法改成绝对路径。
是否可代理xhr post请求,由客户端处理?
NSURLProtocol
通过代理xhr实现post请求拦截,对H5端无侵入。
目前H5侧仅仅支持json数据解析,如果protocol拦截第三方h5 post请求,需返回相应数据类型。
result
以上两种方案对比后,由于编辑器135URLSchemeHandler的缺陷,决定使用xhr代理处理h5侧的post请求,使用urlProtocol拦截离线资源(get)请求。
waitToDo
- h5侧编写代理xhr的js
- 客户apple端编写与代理xhr通信的js
- h5写接口测试页面,后台写测试接口(接口尽量涉及全数据类型),客户端做拦截回调测试
代理圈复杂度xhr小结
能做什么
- 拦截xhr环形复杂度的post请求
- 拦截表单里面xhr焯是什么梗的post请求
其他请求方式,如果wios14.4.1更新了什么kwebview中注册了http、https,其post请求的body仍然会丢失
native交互
- 代理x环路复杂度hr拦截H5 post请求发送给native编辑器哪个好用
window.bridge.call("xhrPOST", params);
/*
xhrPOST是native注册的方法,会引起native回调
params 是此次请求所带的参数(bridge只能传递基本数据类型,对象需做相应处理)
{
data;//请求参数
method;//请求方式
header;//请求header,{}
url;//请求地址
xhrId;//请求id
}
*/
- n算法复杂度ative请求成功数据通过代理xhr返回编辑器未包含main类型怎么解决给H5
[self.webview evaluateJavaScript:[NSString stringWithFormat:@"window.bridge.receiveMessage(%@);",messageString] completionHandler:nil];
/*
receiveMessage是js bridge中注册的方法,会引起js回调
messageString是数据的json字符串,包括
{
xhrId;//请求id
statusCode;//请求状态码
responseText;//请求数据,string
resultType;//数据类型,1表示文本 2表示xml、html 3表示字节流
responseHeaders;// {}
error;//错误描述
}
*/
实现环形复杂度
native数据返回
/*
常见的媒体格式类型如下:
text/html : HTML格式
text/plain :纯文本格式
text/xml : XML格式
image/gif :gif图片格式
image/jpeg :jpg图片格式
image/png:png图片格式
以application开头的媒体格式类型:
application/xhtml+xml :XHTML格式
application/xml: XML数据格式
application/atom+xml :Atom XML聚合格式
application/json: JSON数据格式
application/pdf:pdf格式
application/msword : Word文档格式
application/octet-stream : 二进制流数据(如常见的文件下载)
application/x-www-form-urlencoded : <form encType=””>中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)
另外一种常见的媒体格式是上传文件之时使用的:
multipart/form-data : 需要在表单中进行文件上传时,就需要使用该格式
*/
根据httpResponse里面的content-type判断:
- t环形复杂度ext/p环路复杂度lain、application/json,处理为文本,resulios15tType == 1
- text/html、text/xml、application/xhtml+xml、application/xml、application/atom+x编辑器135ml,处理为文本,resultType == 1
- 剩余类appstore型如果data能成功编码为string,当作文本处理,resultType == 1;否则data转为十六进制字符串,resultType == 3
resultType=3时,需将he时间复杂度xSt编辑器英文ring转为字节流,赋值给xios鲁多多apphr.response
xhr请求的参数传递
- 基本数据类型(int、string、array、dictionary)时,直接传递,webkit会做相应数据类型转换
- fo编辑器哪个好用rm表单中上传文件时,参数中会新ios下载增filapplees数组,对应File会转为字节数组传给native
// files 为存储文件的数组
/* {
filename:fileName
type:mimeType
name:name
file:[uint8]
}*/
其他类型未处理,如Ar编辑器135rayBuffer、Blob
native上传从山神开始的诸天之旅body拼接
// 拼接httpBody
/* 分为2部分
{
key:value;//非文件部分
files:{//文件部分
filename:fileName
type:mimeType
name:name
file:[uint8]
}
}
*/
//示例
--boundraryidString
Content-Dispostion: form-data; name="name"; filename="filename"
Content-Type: "MIMETYPE"
文件部分
--boundraryidString
Content-Dispostion: form-data; name="key"
非文件部分参数值
--boundraryidString--
数据转换
Blob -> NSData
NSData -> Blob
以上为项目中所使用的的编辑器哪个好用两种数据处理方式,劳动复杂度可逆向
具体使ios15用
EHWKWeapplebView的创建
- 直接创建 用法和EHWebView使用一致
- (EHWKWebView *)webView
{
if (!_webView)
{
_webView = [[EHWKWebView alloc] initWithURLString:_URLString];
_webView.configuration.allowsInlineMediaPlayback = YES;//防止自动全屏播放
_webView.configuration.mediaTypesRequiringUserActionForPlayback = NO;
_webView.supportJSInterface = YES;
_webView.supportEmptyBack = YES;
_webView.scrollView.bounces = YES;
_webView.backgroundColor = WHITE_COLOR;
_webView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
_webView.navigationDelegate = self;
_webView.viewController = self;
}
return _webView;
}
- 通过EHWebViewCreatios下载orMan软件复杂度ager创建
- (EHWKWebView *)webView {
if (!_webView) {
_webView = [[EHWebViewCreatorManager manager] getWKWebView];
_webView.originalURLString = _URLString;
_webView.viewController = self;
_webView.navigationDelegate = self;
}
return _webView;
}
EHWebViewCreatorManager 中包含是否预创建webview的策略,其创建只是赋值了一些基础属性,业务属长沙市天气性如urlString、viewController、navigationDelegate等留给外部处理
EHWebView的使用场景
需要使用JSSDK能力的网页使用EHWKWebView,其他场陈思思景如页面展示使用WKWebView即可
Q&A
如何切换uiWebView,wkWebView ?
如何使用提前创建的uiWebView或者wkWebView ?
wkWebView是怎样加cookie的 ?
- 第一次加载时load陈涉世家翻译及原文Request中在request的header里面设置cookie长沙师范学院
- 后续页面内的跳转在wkwebview:decideP编辑器下载olicyForAction焯是什么梗:代理方法中通过注入脚本的方式加cookie
w编辑器和编译器的区别kWebView如何长生十万年注册scheme的 ?
- 获取私有类型
cls = [[[WKWebView new] valueForKey:@"browsingContextController"] class]
- 获取私有方法
sel = NSSelectorFromString(@"registerSchemeForCustomProtocol:")
sel = NSSelectorFromString(@"unregisterSchemeForCustomProtocol:")
- 注册自定义scheme
if ([(id)cls respondsToSelector:sel]) {
// 放弃编辑器警告
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[(id)cls performSelector:sel withObject:scheme];
#pragma clang diagnostic pop
}
wkWebView如何拦截post请ios14.4.1更新了什么求的 ?
通过代理xhr拦截H5页面中的post请求,拦截后交由客户端处理,客户端请求完将数据返回给H5页面,具体操作流程可见代理xhr实现
测试
测试范编辑器哪个好用围
常规上是ios客户端的所有H5应用,但限制于时间和人力,目前仅仅测试核心的H5模块,包括
- 服务联盟
- 云打印
- 工位预定
- 品质核查
- 物业巡检
前面3个属于常规的H5应用,后面2个属于能离线的H5应用appointment(弱网、断网情况下能正常显示页面)
测试标准
使用wkwebview加编辑器和编译器的区别载的H5页面显示、跳转、请求无异常。
H5离线应用相对于常复杂度怎么计算的规应用,在有网条件下验证无误的情况下,还需在断网环境下检验页面是否能正常显示。
一般H5应用的流程能正常走通则说明没问题。
也可以使用两台测试机对比,一台是wkwebview加载显示,另一台是旧的uiwebview加载显示,如果wkwebview的结果和uiwebview一样,则说明没问题。
测试方法环形复杂度
从我的->设置->开发者选项->WKWebView测试->使用UIWebView/WKWeb环形复杂度View,切换为WKWebView后,回到广场选择相应的H5应用进入即可开始验证。
发表回复
要发表评论,您必须先登录。