开发者社区> 问答> 正文

iOS WebView 中的 Cookie场景IP直连的几种方法(1)


WebView 中的 Cookie 处理业务场景“IP直连”方案说明



概述


本文将讨论下类似这样的问题:

  • WKWebView 对于 Cookie 的管理一直是它的短板,那么 iOS11 是否有改进,如果有,如何利用这样的改进?采用 IP 直连方案后,服务端返回的 Cookie 里的 Domain 字段也会使用 IP 。如果 IP 是动态的,就有可能导致一些问题:由于许多 H5 业务都依赖于 Cookie 作登录态校验,而 WKWebView 上请求不会自动携带 Cookie。


WKWebView 使用 NSURLProtocol 拦截请求无法获取 Cookie 信息


iOS11推出了新的 API WKHTTPCookieStore 可以用来拦截 WKWebView 的 Cookie 信息
用法示例如下:
  1.    WKHTTPCookieStore *cookieStroe = self.webView.configuration.websiteDataStore.httpCookieStore;
  2.    //get cookies
  3.     [cookieStroe getAllCookies:^(NSArray<NSHTTPCookie *> * _Nonnull cookies) {
  4.         NSLog(@"All cookies %@",cookies);
  5.     }];
  6.     //set cookie
  7.     NSMutableDictionary *dict = [NSMutableDictionary dictionary];
  8.     dict[NSHTTPCookieName] = @"userid";
  9.     dict[NSHTTPCookieValue] = @"123";
  10.     dict[NSHTTPCookieDomain] = @"xxxx.com";
  11.     dict[NSHTTPCookiePath] = @"/";
  12.     NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:dict];
  13.     [cookieStroe setCookie:cookie completionHandler:^{
  14.         NSLog(@"set cookie");
  15.     }];
  16.     //delete cookie
  17.     [cookieStroe deleteCookie:cookie completionHandler:^{
  18.         NSLog(@"delete cookie");
  19.     }];


利用 iOS11 API WKHTTPCookieStore 解决 WKWebView 首次请求不携带 Cookie 的问题


问题说明:由于许多 H5 业务都依赖于 Cookie 作登录态校验,而 WKWebView 上请求不会自动携带 Cookie。比如,如果你在Native层面做了登陆操作,获取了Cookie信息,也使用 NSHTTPCookieStorage 存到了本地,但是使用 WKWebView 打开对应网页时,网页依然处于未登陆状态。如果是登陆也在 WebView 里做的,就不会有这个问题。
iOS11 的 API 可以解决该问题,只要是存在 WKHTTPCookieStore 里的 cookie,WKWebView 每次请求都会携带,存在 NSHTTPCookieStorage 的cookie,并不会每次都携带。于是会发生首次 WKWebView 请求不携带 Cookie 的问题。
解决方法:
在执行 -[WKWebView loadReques:] 前将 NSHTTPCookieStorage 中的内容复制到 WKHTTPCookieStore中,以此来达到 WKWebView Cookie 注入的目的。示例代码如下:
  1.         [self copyNSHTTPCookieStorageToWKHTTPCookieStoreWithCompletionHandler:^{
  2.             NSURL *url = [NSURL URLWithString:@"https://www.v2ex.com"];
  3.             NSURLRequest *request = [NSURLRequest requestWithURL:url];
  4.             [_webView loadRequest:request];
  5.         }];
  1. - (void)copyNSHTTPCookieStorageToWKHTTPCookieStoreWithCompletionHandler:(nullable void (^)())theCompletionHandler; {
  2.     NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];
  3.     WKHTTPCookieStore *cookieStroe = self.webView.configuration.websiteDataStore.httpCookieStore;
  4.     if (cookies.count == 0) {
  5.         !theCompletionHandler ?: theCompletionHandler();
  6.         return;
  7.     }
  8.     for (NSHTTPCookie *cookie in cookies) {
  9.         [cookieStroe setCookie:cookie completionHandler:^{
  10.             if ([[cookies lastObject] isEqual:cookie]) {
  11.                 !theCompletionHandler ?: theCompletionHandler();
  12.                 return;
  13.             }
  14.         }];
  15.     }
  16. }

这个是 iOS11 的API,针对iOS11之前的系统,需要另外处理。

展开
收起
猫饭先生 2017-10-20 11:18:31 2020 0
0 条回答
写回答
取消 提交回答
问答排行榜
最热
最新

相关电子书

更多
手淘iOS性能优化探索 立即下载
From Java/Android to Swift iOS 立即下载
深入剖析iOS性能优化 立即下载