美文网首页网络
WKWebView对Cookie的处理

WKWebView对Cookie的处理

作者: 聪莞 | 来源:发表于2019-03-26 19:36 被阅读25次

因为WKWebView是通过WebKit内核进行网络处理的,所以我们的NSHTTPCookieStorage里的Cookie是没办法拿到并带进一个请求的。可以通过下面的方法手动添加:

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]];
    NSArray *cookies = [NSHTTPCookieStorage sharedHTTPCookieStorage].cookies;
    NSDictionary *requestHeaderFields = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies];
    //设置请求头
    request.allHTTPHeaderFields = requestHeaderFields;

这种方式只对单个请求有效,一旦URL改变,Cookie还是会丢失,所以我们可以通过WKWebView的代理

  • (void)webView: decidePolicyForNavigationAction: decisionHandler:
    来对每一个request进行Cookie处理
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    [[WKCookieManager shareManager] fixNewRequestCookieWithRequest:navigationAction.request];
    decisionHandler(WKNavigationActionPolicyAllow);
}

- (NSURLRequest *)fixNewRequestCookieWithRequest:(NSURLRequest *)originalRequest{
    NSMutableURLRequest *fixedRequest;
    if ([originalRequest isKindOfClass:[NSMutableURLRequest class]]) {
        fixedRequest = (NSMutableURLRequest *)originalRequest;
    } else {
        fixedRequest = originalRequest.mutableCopy;
    }
    //防止Cookie丢失
    NSDictionary *dict = [NSHTTPCookie requestHeaderFieldsWithCookies:[NSHTTPCookieStorage sharedHTTPCookieStorage].cookies];
    if (dict.count) {
        NSMutableDictionary *mDict = originalRequest.allHTTPHeaderFields.mutableCopy;
        [mDict setValuesForKeysWithDictionary:dict];
        fixedRequest.allHTTPHeaderFields = mDict;
    }
    return fixedRequest;
}
另外一种方式:

可以在WKWebViewConfiguration的userContentController中注入脚本:

    WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
    WKUserContentController *controller = [[WKUserContentController alloc] init];
    [controller addUserScript:[[WKCookieManager shareManager] futhureCookieScript]];
    configuration.userContentController = controller;

- (WKUserScript *)futhureCookieScript{
// source 就是我们要调用的 JS 函数或者我们要执行的 JS 代码
// injectionTime 这个参数我们需要指定一个时间,在什么时候把我们在这段 JS 注入到 WebVeiw 中,它是一个枚举值,WKUserScriptInjectionTimeAtDocumentStart 或者 WKUserScriptInjectionTimeAtDocumentEnd
// MainFrameOnly 因为在 JS 中,一个页面可能有多个 frame,这个参数指定我们的 JS 代码是否只在 mainFrame 中生效
- initWithSource:injectionTime:forMainFrameOnly:
    WKUserScript * cookieScript = [[WKUserScript alloc] initWithSource:[self cookieString] injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
    return cookieScript;
}

- (NSString *)cookieString
{
    NSMutableString *script = [NSMutableString string];
    [script appendString:@"var cookieNames = document.cookie.split('; ').map(function(cookie) { return cookie.split('=')[0] } );\n"];
    for (NSHTTPCookie *cookie in [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]) {

        if ([cookie.value rangeOfString:@"'"].location != NSNotFound) {
            continue;
        }

    NSString *string = [NSString stringWithFormat:@"%@=%@;domain=%@;path=%@",
                        cookie.name,
                        cookie.value,
                        cookie.domain,
                        cookie.path ?: @"/"];
    
    if (cookie.secure) {
        string = [string stringByAppendingString:@";secure=true"];
    }

        [script appendFormat:@"if (cookieNames.indexOf('%@') == -1) { document.cookie='%@'; };\n", cookie.name, string];
    }
    return script;
}

iOS11之后

iOS11之后,有一个更简便的方法:

/*! @abstract Returns the cookie store representing HTTP cookies in this website data store. */
@property (nonatomic, readonly) WKHTTPCookieStore *httpCookieStore API_AVAILABLE(macosx(10.13), ios(11.0));

//发送请求前插入cookie;
    NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];
    WKHTTPCookieStore *cookieStore = [WKWebsiteDataStore defaultDataStore].httpCookieStore;
    
    if (cookies.count > 0) {
        for (NSHTTPCookie *cookie in cookies) {
            [cookieStore setCookie:cookie completionHandler:^{
                
            }];
        }
    }

相关文章

  • WKWebView对cookie的处理

    小编在网上查了很多wkwebview怎么去保存cookie,怎么保证cookie不丢失的资料,可大多发现说的不怎么...

  • WKWebView对Cookie的处理

    因为WKWebView是通过WebKit内核进行网络处理的,所以我们的NSHTTPCookieStorage里的C...

  • H5遇到的常见问题

    iOS WKWebView cookie 写入慢以及易丢失 现象: 原因:WKWebView 对 NSHTTPCo...

  • 再会WKWebView

    有关WKWebView处理cookie问题,又多次测试,发现并不需要在 初识WKWebView那么麻烦,有更简...

  • WKWebView处理cookie问题

    问题描述 公司接入第三方H5接入,页面上需要输入用户名和密码,使用WKWebView总是记不住密码(应该是有时能记...

  • 关于WKWebView的Cookie处理

    WKWebView的坑相信大家已经踩过很多了.之前cookie的问题已经处理过一些了.但是这次又出现了新坑.在第一...

  • iOS WKWebView Cookie的处理

    1. 最近接到一个模块迁移的功能,就是把H5页面的某个功能模块嵌入的App中...其中涉及到一些原生和JS交互,c...

  • iOS开发-WKWebView设置cookie

    1.初始化WKWebView时设置cookie 2.WKWebView已经存在时,设置cookie

  • APP中的cookie

    wkwebview中的cookie: 1:wkwebview默认可以携带原生接口种下的cookie;iOS8以后,...

  • 疑难问题收集

    WKWebview 在重定向时 cookie 丢失 1.WKWebview 在重定向时 cookie 丢失: 1....

网友评论

    本文标题:WKWebView对Cookie的处理

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