系列文章:
- 《37- WKWebView项目实践分享(一)- UIWebView回顾介绍》
- 《43- WKWebView项目实践分享(二)- WKWebView介绍》
- 《38- WKWebView项目实践分享(三)- native和webView交互》
- 《39- WKWebView项目实践分享(四) - 先了解下Cookie》
- 《40- WKWebView项目实践分享(五)- WKWebView如何加Cookie》
- 《41- WKWebView项目实践分享(六)- 项目实践:User Agent、跨域、重定向及其它》
第一坑: WKProcessPool
知识点复习:
看过腾讯Bugly的那篇 《WKWebView 那些坑》,我们知道WKProcessPool可以解决不同的WKWebView 之间共享 Cookie(session Cookie and persistent Cookie)数据, 具体的做法是创建一个单利,来持有WKProcessPool。
场景:在H5中点击一些链接,它是会在当前的webView基础上,重新创建一个webView来展示的,而不是在当前webView上展示。 具体创建方式就是回调在第二章中执行WKUIDelegate的代理方法。
解决这一个问题的方式,具体代码如下:
WKWebViewConfiguration * webConfiguration = [[WKWebViewConfiguration alloc]init];
webConfiguration.processPool = [LLWKProcessPoolUtil sharedInstance].wkProcessPool;
@interface LLWKProcessPoolUtil : NSObject
+ (LLWKProcessPoolUtil *)sharedInstance;
/// WKProcessPool
@property (nonatomic, strong) WKProcessPool *wkProcessPool;
/// 销毁wkProcessPool单例属性
- (void)destroyInstance;
@end
#import "LLWKProcessPoolUtil.h"
@implementation LLWKProcessPoolUtil
+ (LLWKProcessPoolUtil *)sharedInstance
{
static dispatch_once_t once;
static YCWKProcessPoolUtil * __singleton__;
dispatch_once( &once, ^{
__singleton__ = [[LLWKProcessPoolUtil alloc] init];
});
return __singleton__;
}
#pragma mark - 不同webView中的Cookie
static WKProcessPool *__singlePool__ = nil;
static dispatch_once_t onceTokenPool;
- (WKProcessPool *)wkProcessPool
{
dispatch_once( &onceTokenPool, ^{
__singlePool__ = [[WKProcessPool alloc] init];
});
return __singlePool__;
}
- (void)destroyInstance
{
onceTokenPool = 0;
__singlePool__ =nil;
}
@end
遇到的坑:
这样虽然可以解决创新创建的WKWebView的cookie访问问题,但是因为是单利持有的,当我们切换用户登录之后,webView会出现带有上一个用户Cookie的问题,这对于设计到积分和金钱的业务就很麻烦了,H5以为是上一个用户登录的。 解决方法, 切换登录的时候,将单利持有的proceressPool销毁掉,代码如下:
[LLWKProcessPoolUtil destroyInstance];
但是这样,我们会有另外一个问题,发生在iOS8~iOS10,proceressPool销毁之后进入再次进入webView进行登录,按照我们第四章中的Cookie策略,Cookie死活没有了。 比如得重新重新走一遍创建WKWebView,然后请求url的步骤才能生效。 好吧,原因是这个时候,document.Cookie也随之丢失了。
解决办法:
解决方法,你也想到了,重新给document.Cookie赋值。
第二坑:User Agent
知识点复习:
我们加User Agent,就是方便H5后台知道,这个H5页面是从咱公司APP进去的。方便识别来源,做大数据和广告数据统计。
遇到的坑:
之前的写法,是直接股改webView原生的User Agent。后来上线过程中,遇到一个广告客户的H5链接怎么都打不开,一直在重定向循环。
但是我们新建一个纯净WKWebView是可以正常打开的。经过仔细排查,才发现是User Agent的锅。有些H5的后台是根据设备浏览器上传的User Agent来判断设备的webView是否安全或者是否可以让该webView打开网页。很显然,他们是根据webView原生的来判定的。
解决办法:
设置的时候不要覆盖手机原生User Agent, 我们要把我们自己公司的自定义User Agent字段追加到原生后边。也就是『原生User-Agent + 我们自己的User Agent』。比如:
Mozilla/5.0 (iPhone; CPU iPhone OS 12_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/16B91 LiLong=123445 LiLongBBB=Baidu
第三坑:后台H5页面不支持https://
遇到的坑:
最新测试反馈一个H5页面有问题, 具体是在iOS上某些点击不跳转. 开始以为是webView的问题, 新建项目加载这个链接也有问题. 并且在mac电脑的浏览器上也有相同问题. 但是同事打开就没问题. 奇怪了. 都是mac电脑, 都是一个浏览器. 难道是链接的锅? 后来发现还真是, 我这边加载的"https://xxxxxxxx", 同事加载的是"http://xxxxxxxx". "https://xxxxxxxx"这个有问题.
解决办法:
通知H5, iOS加载"http://xxxxxxxx"
第四坑:Request Header中写入自定义Host导致请求个别网页失败
遇到的坑:
上一个离职的同事在写webView请求的时,手动在Request Header
中设置了一次Host
,这么做的原因不太清楚,可能是因为服务器识别请求来源。之后很长时间里也没有问题,但是前段时间有一天请求某个webView总是白屏,经过排除法,最终确定是因为重写了Host
。代码中设置Host
的方法是这样的:
[request addValue:request.URL.host forHTTPHeaderField:@"Host"];
解决办法:
不手动在Request Header
设置了一遍Host
,删除这一行代码。
交流
希望能和大家交流技术
Blog:http://www.lilongcnc.cc