美文网首页
WKWebView Cookie共享 OC JS互相调用

WKWebView Cookie共享 OC JS互相调用

作者: TeeMo_Yan | 来源:发表于2018-12-22 18:14 被阅读66次

    WKWebView的Cookie共享在项目中用法为下面3个步骤

    注:WKCookieManager单利 在下面Demo中

    1.  //注入 JS 代码块,解决跨域丢失问题

       WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];

        WKUserContentController *contoller = [[WKUserContentController alloc] init];

        [contolleraddUserScript:[[WKCookieManager shareManager] futhureCookieScript]];

        configuration.userContentController= contoller;

    2.  //拼接同步到 NSHTTPCookieStorage 中的 Cookei

        [self.webView loadRequest:[[WKCookieManager shareManager]cookieAppendRequest:@"http://www.baidu.com"]];

    3.  //防止新的跳转 cooki 丢失问题

    在WKNavigationDelegate的方法中调用 

      [[WKCookieManager shareManager] fixNewRequestCookieWithRequest:navigationAction.request];

    - (void)webView:(WKWebView*)webView decidePolicyForNavigationAction:(WKNavigationAction*)navigationAction decisionHandler:(void(^)(WKNavigationActionPolicy))decisionHandler {

        [[WKCookieManager shareManager] fixNewRequestCookieWithRequest:navigationAction.request];

        decisionHandler(WKNavigationActionPolicyAllow);

    }

    通过Charles青花瓷抓包来查看Cookie 是否设置成功。注意清除缓存

    JS调用OC  

     //方法注入

    // window.webkit.messageHandlers..postMessage() for all  前端要这样写,页面退出前需要移除

        [self.webView.configuration.userContentController addScriptMessageHandler:self name:@"JSSendMessageToOC"];

    - (void)viewDidDisappear:(BOOL)animated{

        [superviewDidDisappear:animated];

        //必须移除 否则VC不释放

        [self.webView.configuration.userContentController  removeScriptMessageHandlerForName:@"JSSendMessageToOC"];

    }

    #pragma mark - WKScriptMessageHandler

    - (void)userContentController:(WKUserContentController*)userContentController didReceiveScriptMessage:(WKScriptMessage*)message{

        NSLog(@"%@---%@",message.name,message.body);

        //  第一个参数为f方法名(自行和前端协商格式)

        NSDictionary*dic = message.body;

        NSString*common_mothed = dic.allKeys.firstObject;

        //注入的公共方法

        if(![message.nameisEqualToString:@"JSSendMessageToOC"]) {

            return;

        }

        if([common_mothedisEqualToString:@"XXX"]) {

        }

    }

    OC 调用JS

    - (void)ocSendMessageToJs:(NSString*)method parameter:(NSString*)para{

        NSString *jsStr2 = [NSString stringWithFormat:@"%@(%@)",method,para];

        [self.webView evaluateJavaScript:jsStr2 completionHandler:^(id _Nullable result, NSError * _Nullable error) {

            NSLog(@"%@----%@",result, error);

        }];

    }

    Demo 示例:

    说明:

    1.在ViewController中加载了一个UIWebview ,通过设置Cookie模拟登录后拿到的Cookie (真实开发中可忽略)

    加载时,我通过Charles 抓包(此时还未点击登录成功设置Cookie按钮)结果如下

    未点击设置Cookie

    2.点击了跳转WKWebView ,来看下WKWebview的Cookie

    未设置WKWebview的Cookie

    3.然后返回,点击登录成功设置Cookie ,然后刷新UIWebVIew,通过Charles 查看UIWebView的Cookie

    发现多了一个我们自己设置的TeeMo_Cookie_WebView

    已经设置UIWebView的Cookie

    4.点击跳转WKWebView ,通过Charles 查看WKWebView的Cookie

    已经设置WKWebView的Cookie

    此时都有Cookie了,我们返回,然后再进去,发现WKWebView的Cookie依然存在。


    核心代码

    /*

     拼接同步到 NSHTTPCookieStorage 中的 Cookei, 第一次尝试如何让 URL 刚开始加载是带上自己的 Cookie,可以通过抓包工具查看。

     @paramurl 要加载的URL

     @return拼接了 Cookie 字段后的请求

     */

    - (NSURLRequest*)cookieAppendRequest:(NSString*)url{

        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];

        NSArray *cookies = [NSHTTPCookieStorage sharedHTTPCookieStorage].cookies;

        //Cookies数组转换为requestHeaderFields

        NSDictionary *requestHeaderFields = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies];

        //设置请求头

        request.allHTTPHeaderFields= requestHeaderFields;

        NSLog(@"%@",request.allHTTPHeaderFields);

        return request;

    }

    /**

     跨域请求丢失问题

     @return注入的 JS 代码块

     */

    - (WKUserScript*)futhureCookieScript{

        WKUserScript * cookieScript = [[WKUserScript alloc] initWithSource:[self cookieString] injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];

        return cookieScript;

    }

    - (NSString*)cookieString

    {

        NSMutableString *script = [NSMutableString string];

        [scriptappendString:@"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;

            }

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

        }

        return script;

    }

    /**

     解决新的跳转 Cookie 丢失问题

     @paramoriginalRequest 拦截的请求

     @return带上 Cookie 的请求

     */

    - (NSURLRequest*)fixNewRequestCookieWithRequest:(NSURLRequest*)originalRequest{

        NSMutableURLRequest *fixedRequest;

        if ([originalRequest isKindOfClass:[NSMutableURLRequest class]]) {

            fixedRequest = (NSMutableURLRequest*)originalRequest;

        }else{

            fixedRequest = originalRequest.mutableCopy;

        }

        NSDictionary *dict = [NSHTTPCookie requestHeaderFieldsWithCookies:[NSHTTPCookieStorage sharedHTTPCookieStorage].cookies];

        if(dict.count) {

            NSMutableDictionary *mDict = originalRequest.allHTTPHeaderFields.mutableCopy;

            [mDictsetValuesForKeysWithDictionary:dict];

            fixedRequest.allHTTPHeaderFields= mDict;

        }

        return fixedRequest;

    }

    Demo :https://github.com/TeeMoYan/TMWKWebViewDemo.git

    相关文章

      网友评论

          本文标题:WKWebView Cookie共享 OC JS互相调用

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