1、WK 脚本注入Cookies信息-代码示例
/* Ajax、iframe请求配置cookies */
- (WKWebViewConfiguration *)configuration {
if (!_configuration) {
_configuration = [[WKWebViewConfiguration alloc] init];
_configuration.allowsInlineMediaPlayback = YES;
if (@available(iOS 10.0, *)) {
if ([_configuration respondsToSelector:@selector(mediaTypesRequiringUserActionForPlayback)]) {
_configuration.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
}
} else if(@available(iOS 9.0, *)){
if([_configuration respondsToSelector:@selector(setRequiresUserActionForMediaPlayback:)]) {
_configuration.requiresUserActionForMediaPlayback = NO;
}
} else if([_configuration respondsToSelector:@selector(setMediaPlaybackRequiresUserAction:)]){
_configuration.mediaPlaybackRequiresUserAction = NO;
}
WKUserContentController* userContentController = [[WKUserContentController alloc] init];
_configuration.userContentController = userContentController;
/*
document.cookie='uid=123456;path=/;domain=.baidu.com';
document.cookie='_DC=1;path=/;domain=.baidu.com';
document.cookie='session=eddf8312293823dcabd903;path=/;
domain=.baidu.com';document.cookie='os=iOS;path=/;domain=.baidu.com';
*/
NSString *strDocumentCookie = [self getCookiesForWKWebview];
WKUserScript * cookieScript = [[WKUserScript alloc] initWithSource:strDocumentCookie injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
[userContentController addUserScript:cookieScript];
}
return _configuration;
}
2、html加载问题-同域重定向302
html资源加载一般是不会去判断登录态的,WKWebView在加载同域名的第一个html文件时,没有带cookie信息,所以直接在加载html的时重定向去判断登录态就会有问题。
方案1:在webView加载request前,配置cookie信息(只对该request生效-mainFrame)。
/* 配置cookie信息 */
- (void)loadRequest {
NSMutableDictionary *cookieDic = [MKCookieManager getCookieConfig];
NSMutableString *cookieValue = [NSMutableString stringWithFormat:@""];
for (NSString *key in cookieDic) {
NSString *appendString = [NSString stringWithFormat:@"%@=%@;", key, [cookieDic valueForKey:key]];
[cookieValue appendString:appendString];
}
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:self.strUrl]];
if ([cookieValue isNotEmpty]) {
[request setValue:cookieValue forHTTPHeaderField:@"Cookie"];
}
[self.webView loadRequest:request];
}
方案2:在APP启动或者重新登录后,预加载一个同根域名的常规h5页面(cookie更新不及时)。
/* 启动或者登录后 TabbarVC*/
- (void)loadRequest {
if (self.webView) {
[self.webView stopLoading];
self.webView.delegate = nil;
self.webView = nil;
}
MKWebView* webView = [[MKWebView alloc] initWithFrame:CGRectZero delegate:self];
self.webView = webView;
NSURLRequest* req = [NSURLRequest requestWithURL:[NSURL
URLWithString:@"https://host/path.html"]];
[self.webView loadRequest:req];
}
- (NSString *)documentCookieForWKWebview {
return [MKCookieManager documentCookieForWKWebview:[NSURL URLWithString:@"https://host/path.html"]];
}
3、WK页面重定向-跨域cookie问题
第一个请求是www.yuminga.com,接着页面302跳转到www.yumingb.com,这个时候www.yumingb.com这个请求就可能因为没有携带cookie而无法访问。
方案1:对比跳转URL与页面URL的host,如果为跨域,通过WKUserScript在注入cookie信息。
/* 跨域重定向-同步cookie */
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
NSString* URLString = ([self.crossDominLink isNotEmpty] ? self.crossDominLink: self.pageUrl);
NSURL* currentURL = [NSURL URLWithString:URLString];
if (![currentURL.host isEqualToString:navigationAction.request.URL.host]) {
//跨域重定向注入cookieScript
NSString *strDocumentCookie = [MKCookieManager genDocumentCookieForWKWebview:navigationAction.request.URL];
WKUserScript * cookieScript = [[WKUserScript alloc] initWithSource:strDocumentCookie injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
[webView.configuration.userContentController addUserScript:cookieScript];
self.crossDominLink = navigationAction.request.URL.absoluteString;
}
decisionHandler(WKNavigationActionPolicyAllow);
}
方案2:对比跳转URL与页面URL的host,如果为跨域且未做处理,拦截该跳转,重新配置request的cookie信息,再loadRequest一下。(只适合加载mainFrame请求,iframe无效)
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
NSURL* currentURL = [NSURL URLWithString:self.pageUrl];
if ((![self.crossDomainURL isEqualToString:navigationAction.request.URL.absoluteString]) && (![currentURL.host isEqualToString:navigationAction.request.URL.host])) {
self.crossDomainURL = navigationAction.request.URL.absoluteString;
NSMutableURLRequest* request = [navigationAction.request mutableCopy];
NSString* cookieValue = @"session=720bff297ea3866696380368f81fc4e4;token_id=NzIwYmZmMjk3ZWEzODY2Njk2MzgwMzY4ZjgxZmM0ZTQ=;uid=123456;";
[request setValue:cookieValue forHTTPHeaderField:@"Cookie"];
[webView loadRequest:request];
decisionHandler(WKNavigationActionPolicyCancel);
} else {
decisionHandler(WKNavigationActionPolicyAllow);
}
}
4、CookieStorage同一根域名name重复问题
现象:APP未登录时访问接口,客户端没有设置session,后端接口会回写一个session,导致NSHTTPCookieStorage也会多出一个session。
方案:在退出登录、重新登录后,清除掉NSHTTPCookieStorage中与用户相关的cookies,再进行cookies的赋值。
5、WK同时配置了根域名和url-host的cookie
现象:页面请求时,所有的cookie-name都复制多了一份,出现同个cookie-name双份的现象。
方案:只需要配置根域名的cookies,去掉url-host的cookies配置。
6、WKWebView哪些坑
https://www.jianshu.com/p/a9087a07f671
/* JS-alert crash容错 */
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)())completionHandler {
if (!self.isLoadFinish) {
completionHandler();
return;
}
if (self.isViewLoaded && self.view.window) {
MKAlertView *alertView = [[MKAlertView alloc] initWithTitle:@"温馨提示" message:message confrimTitle:@"确定" confrimCallBack:^{
completionHandler();
}];
[alertView show];
} else {
completionHandler();
}
}