IOS WKWebView与Cookie问题梳理

您所在的位置:网站首页 跨域cookie问题 IOS WKWebView与Cookie问题梳理

IOS WKWebView与Cookie问题梳理

2024-01-07 14:40| 来源: 网络整理| 查看: 265

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只支持同域设置 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; }

备忘:iframe通过src加载会触发decidePolicyForNavigationAction代理;每个frame都有自己的window对象,无论是mainframe还是iframe。

2、html加载问题-同域重定向302

html资源加载一般是不会去判断登录态的,WKWebView在加载同域名的第一个html文件时,没有带cookie信息,所以直接在加载html的时重定向去判断登录态就会有问题。

解决方案:在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]; }

3、WK页面重定向-跨域cookie问题

第一个请求是www.domainA.com,接着页面302跳转到www.domainB.com,这个时候www.domainB.com这个请求就可能因为没有携带cookie而无法访问。

解决方案1:对比跳转URL与页面URL的host,如果为跨域,通过WKUserScript在注入cookie信息(document.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同时配置了根域名和子域名的cookie

现象:页面请求时,所有的cookie-name都复制多了一份,出现同个cookie-name双份的现象。

解决方案:只需要配置根域名的cookies,去掉子域名的cookies配置。

6、WK中iframe的JSBridge调用问题

WKWebView添加JSBridge的API-addScriptMessageHandler支持所有frames,包括mainframe和iframe。

在IOS端add一个JSBridge,H5页面不同的frame会挂载不同的JSBridge(window.webkissageHandlers.JSBridge)。

7、WKWebView哪些坑

滑动验证页面

/* 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(); } }



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3