美文网首页iOS假装进步
39- WKWebView(三) - Cookie了解一下

39- WKWebView(三) - Cookie了解一下

作者: 春田花花幼儿园 | 来源:发表于2018-04-22 12:31 被阅读101次

    在开始Cookie解决方案之前,我们先来简单了解一下Cookie。

    如果你之前没有接触过Cookie,那么只需要记住Cookie是我们日常浏览的网页页面为了识别具体的用户身份,而在request Header加带的一种数据。有了这个数据,你要浏览的的网页就知道你是哪个用户。
    举个例子:如果浏览网站的时候没有Cookie或者Cookie失效了,那么就会出现这种情况。你隔了好多天访问微博网页,点击的标签明明之前保存的是你登录之后的微博首页,可以直接看到你的好友动态。但是现在它却给你跳转了登录页面先要你登录。就是因为你Cookie失效导致的。微博没办法判断你是否是有效用户了。

    另外,我们需要特别注意,在页面跳转的时候,网站有时候会自己在request Header中加入一些Cookie,也作为身份校验的一部分。


    request Http Header

    如何设置和获取Cookie

    首先Cookie可以由native端设置也可以由服务端来设置。

    native端设置了Cookie之后,保存在request Header当中。网站自己想要获取这个Cookie,其中一种方式是通过JS的原生API方法document.cookie获取。

    需要注意的是,native端也可以通过操作document.cookie的方式,达到管理(增删改查)网页中document.cookie的目的。 这一点很重要,因为在之后的WKWebView关于Cookie的解决方案中会用的。

    还有,服务器在request过程中也会设置一些Cookie,服务器设置Cookie是在服务器开始响应的时候,通过response header的一个set-cookie,专门用来设置cookie。

    那么,如果客户端想要打印出webView中的Cookie,就有四个地方可选了:

    1. native端设置Cookie的时候
    2. 获取request Header
    3. 获取document.cookie的内容
    4. 获取response header中的set-cookie

    第一个,我们需要知道iOS这边管理Cookie会用到两个类NSHttpCookieStorage和WKHttpCookieStore。具体关于这两个使用,后面文章会提到,这里只看看获取的方法:

    + (void)logCookiesFromHTTPCookieStore
    {
        if (@available(iOS 11.0, *)) {
            WKWebsiteDataStore *store = [WKWebsiteDataStore defaultDataStore];
            [store.httpCookieStore getAllCookies:^(NSArray<NSHTTPCookie *> * cookies) {
                [cookies enumerateObjectsUsingBlock:^(NSHTTPCookie * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                    NSLog(@"-->count:%zd; name:%@; value:%@",cookies.count, obj.name, obj.value);
                    
                }];
            }];
        }
        else {
            NSArray *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage].cookies;
            for (NSHTTPCookie *cookie in cookieJar) {
                NSLog(@"-->count:%zd; name:%@; value:%@",cookieJar.count, cookie.name, cookie.value);
            }
        }
    }
    

    第二个,直接在WKUINavigationDelegate中的decidePolicyForNavigationAction打印就来可以。
    第三个,方式比较多,可以使用User Script和Script Message的方式,可以翻看上一篇文章《38- WKWebView(二) - native和WebView交互》
    第四个,需要在在WKUINavigationDelegate中的decidePolicyForNavigationResponse打印相关数据。

    + (void)logCookiesFromNavigationResponse:(NSHTTPURLResponse *)response
    {
        // FIXME:获取Cookie!!!
        NSArray *cookies =[NSHTTPCookie cookiesWithResponseHeaderFields:[response allHeaderFields] forURL:response.URL];
        // 读取wkwebview中的cookie 方法1
        for (NSHTTPCookie *cookie in cookies) {
            //[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
            NSLog(@"-->wkwebview中的cookie:%@", cookie);
        }
        
        // -------------------- 分割线
        // 读取wkwebview中的cookie 方法2 读取Set-Cookie字段
        NSString *cookieString = [[response allHeaderFields] valueForKey:@"Set-Cookie"];
        NSLog(@"wkwebview中的cookie:%@", cookieString);
        // 看看存入到了NSHTTPCookieStorage了没有
        NSHTTPCookieStorage *cookieJar2 = [NSHTTPCookieStorage sharedHTTPCookieStorage];
        for (NSHTTPCookie *cookie in cookieJar2.cookies) {
            NSLog(@"NSHTTPCookieStorage中的cookie%@", cookie);
        }
    }
    

    Cookie的属性和创建

    Cookie的参数主要有Domain、Path、Name、Value、Expires,另外还有两个需要注意的参数Secure、HttpOnly。

    其中:

    • Domain:表示域名,比如www.baidu.com
    • Path: 表示路径,比如 "/"、"/shop/book"
    • Name: 表示Cookie的名字
    • Value:表示Cookie要带的信息
    • Expires:表示Cookie的失效日期
    • Secure: 如果设置为ture,表明这个Cookie只在Https或者其它安全请求协议下,才被发送到服务器。默认不设置此项。
    • HttpOnly:如果设置为ture,表明不能通过JS代码去管理被设置的这个Cookie。默认不设置此项。

    接下来,你可以在请求任意网站的时候,给这个网站的request Header中加上自定义的Cookie。只要这个Cookie和这个网站官方使用的Cookie名字不要冲突就好。需要注意,Domain、Path、Name、Value这四个属性是必须都有,Cookie才能有效。上代码:

    {
        WKWebView *webView = [[WKWebView alloc] initWithFrame:[UIScreen mainScreen].bounds];
        NSURL *url = [NSURL URLWithString:@"http://www.lilongcnc.cc"];
        NSURLRequest *request = [NSURLRequest requestWithURL:url];
        [self addCookie];
        [webView loadRequest:request];
        [self.view addSubview:webView];
        
    }
    
    - (void)addCookie
    {
        NSDictionary *mCookProperties = @{
                                          NSHTTPCookieDomain: @".lilongcnc.cc",
                                          NSHTTPCookiePath: @"/",
                                          NSHTTPCookieName: @"laurenKey",
                                          NSHTTPCookieValue:  @"laurenValue",
                                          };
        
        NSHTTPCookie *myCookie = [NSHTTPCookie cookieWithProperties:mCookProperties];
        [self saveCookie:myCookie];
    }
    
    // 添加Cookie到WebView的Cookie管理器
    - (void)saveCookie:(NSHTTPCookie *)cookie
    {
        if (@available(iOS 11.0, *)) {
            WKWebsiteDataStore *store = [WKWebsiteDataStore defaultDataStore];
            [store.httpCookieStore setCookie:cookie completionHandler:^{
            }];
            
            
        } else {
            [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
            [[NSUserDefaults standardUserDefaults] synchronize];
        }
    }
    

    这里有个需要注意的地方,Path的路径/前边不要加"."。web资源路径和PC路径还是有区别的。 你见过 $ cd ./Home/User,但是你肯定没见过http://www.baidu.com./home.html

    参考

    交流


    希望能和大家交流技术
    Blog:http://www.lilongcnc.cc


    相关文章

      网友评论

        本文标题:39- WKWebView(三) - Cookie了解一下

        本文链接:https://www.haomeiwen.com/subject/fboqlftx.html