iOS 和 H5 页面交互(WKWebview 和 UIWebview cookie 设置)

iOS 和 H5 页面交互(WKWebview 和 UIWebview cookie 设置)

主要记录关于cookie相关的坑

1. UIWebview

1. UIWebview 相对比较简单 直接通过 NSHTTPCookieStorage 设置cookie就能实现。

代码部分

```
  NSURL *cookieHost = [NSURL URLWithString:self.domain];
// 设定 cookie
NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:
                        [NSDictionary dictionaryWithObjectsAndKeys:
                         [cookieHost host],NSHTTPCookieDomain,[cookieHost path],NSHTTPCookiePath,self.cookieKey,NSHTTPCookieName,self.cookieValue,NSHTTPCookieValue,nil]];
// 加入cookie
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
```

2. 如果在第一次请求的时候需要在HTTPRequest 通过setValueForKey设置 HeaderValue

2. WKWebview

在使用WKWebview的时候也是需要分两种情况传递:

  • 1.HTTPRequest 请求URL的时候携带 如后端PHP获取 cookie
  • 2.注入js 目的是让前端从页面里边获取到cookie 可以通过在document.cookie 设置 通过WKWebview 初始化时候把js传递过去

    `WKUserScript * cookieScript = [[WKUserScript alloc] initWithSource: cookieValue injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];

  • 3.NSHTTPCookieStorage 似乎不携带没问题,因为我们目前没有通过这个传递cookie

网上参考别人的方法是要实现下面几个步骤,但是我们项目并没有按照这三种必要方式,但是可以做个参考:

WKWebview三个处理步骤: (1)iOS11,WKHTTPCookieStore 直接传递。(如果是只支持iOS11,下面两步可以不做); (2)iOS8-iOS10, js注入; (3)PHP携带cookie方式

相关代码

#pragma mark - WKWebview
// iOS11
- (void)setWkCookie:(WKWebView *)wkWebview completionHandler:(nullable void (^)(void))comple {
    
    NSURL *cookieHost = [NSURL URLWithString:self.domain];
    // 设定 cookie
    NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:
                            [NSDictionary dictionaryWithObjectsAndKeys:
                             [cookieHost host],//                             [NSDate dateWithTimeIntervalSinceNow:30*60*60],NSHTTPCookieExpires,nil]];
    
    // 加入cookie
    //发送请求前插入cookie;
    if (@available(iOS 11.0,*)) {
        WKHTTPCookieStore *cookieStore = wkWebview.configuration.websiteDataStore.httpCookieStore;
        [cookieStore setCookie:cookie completionHandler:^{
            
            comple?comple():nil;
        }];
    } else {
        
        
    }

}

// JS携带cookie的形式
- (void)setWkJsCookie:(WKUserContentController *)userContentController {
    // 单个cookie,多个的话,再加上document.cookie ='%@=%@';一次
    NSString *cookieStr = [NSString stringWithFormat:@"document.cookie ='%@=%@';",self.cookieValue];
    WKUserScript * cookieScript = [[WKUserScript alloc] initWithSource: cookieStr injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
    [userContentController addUserScript:cookieScript];
}

// PHP携带cookie的形式
- (void)setWkPHPCookie:(NSMutableURLRequest *)request {
    //通过host关联cookie。
    NSMutableDictionary *cookieDic = [NSMutableDictionary dictionary];
    NSMutableString *cookieValue = [NSMutableString stringWithFormat:@""];
    NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
    for (NSHTTPCookie *cookie in [cookieStorage cookies]) {
        [cookieDic setObject:cookie.value forKey:cookie.name];
    }
    if ([cookieDic objectForKey:[CookieManager shareInstance].cookieKey]) {
        [cookieDic removeObjectForKey:[CookieManager shareInstance].cookieKey];
    }
    
    // cookie重复,先放到字典进行去重,再进行拼接
    for (NSString *key in cookieDic) {
        NSString *appendString = [NSString stringWithFormat:@"%@=%@;",key,[cookieDic valueForKey:key]];
        [cookieValue appendString:appendString];
    }
    
    [cookieValue appendString:[NSString stringWithFormat:@"%@ = %@;",self.cookieValue]];
    [request addValue:cookieValue forHTTPHeaderField:@"Cookie"];
}
#pragma mark - Webview
// 客户端添加cookie
- (void)setWebCookie {
    
    NSURL *cookieHost = [NSURL URLWithString:self.domain];
    // 设定 cookie
    NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:
                            [NSDictionary dictionaryWithObjectsAndKeys:
                             [cookieHost host],nil]];
    // 加入cookie
    [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
}

2.WKWebview 有跨域问题

* 最后要说的是以上方法如果 考虑跨域问题的话,UIWebView 是不会出现的,但是WKWebview是不允许跨域的,这个也是苹果考虑到安全性的方面,但是是可以处理的,目前我们的方案是以下两种

1.前端通过获取到cookie后 重新种植一下cookie ,通过 .xxx.com 模糊种植

2.让后端来处理,可以把用户相关信息如 uid传递给前端。

相关文章

背景 前端时间产品经理决定使用百度统计,使得 工程B 中原统计sdk-友盟统计,需要被去除。之前尝试去除...
结论: alloc负责分配内存和创建对象对应的isa指针; init只是返回alloc生成的对象。 所以alloc后,多次...
更新 如果UI愿意把启动图切割成n份,按一定约束在launchscreen.storyboard中进行排版,启动图效果会更好...
最近在看一本书《Effective OC 2.0》,今天看到有个tip是OC适中循环各自优劣性,作者最终推荐此块循环。...
// // ViewController.m // paintCodeTestOC //gif // Created by LongMa on 2019/7/25. // #import &a...
背景介绍 一般情况下,出于省电、权限、合理性等因素考虑,给人的感觉是很多奇怪的需求安卓可以实现,但...