1.cookie
1).cookie的作用
客户端访问服务端的时候,服务端返回给的一些信息,放着cookie里面.然后客户端下次访问带着返回的cookie信息,服务端就知道用户信息了.(所以cookie就是用来记录客户端用户信息)
2).cookie持续时间
cookie分会话cookie和持久cookie,如果是会话cookie关闭浏览器(客户端),该cookie就删除了.如果是持久cookie的话,在关闭浏览器(客户端),cookie会默认存储到本地. 会话cookie和持久cookie区别在于,有没有设置expiresDate 和 sessionOnly , 如果设置了expireDate的值 , sessionOnly 值为FALE 那么kill掉程序,cookie会默认保存到沙盒中.
2.与Cookie相关的类
1).NSHTTPCookieStorage 这是一个单列类,用来管理cookie的增删改查.
2).NSHTTPCookie 具体的HTTP请求Cookie数据对象
3.Cookie的操作和使用 1).手动创建Cookie
2).获取cookie
3).删除cookie
4).本地化cookie
5).设置cookie
4 用不用cookie
1).NSHTTPCookieStorage没有像cache一样提供init方法,因此我们也没法指定自己的cookie对象用于缓存。
猜测苹果压根就没想开放出不同session用不同的cookie对象。注意NSHTTPCookie是提供了init方法的。
虽然不能指定cookie的存储对象,但是我们可以选择用不用cookie。当某个session的所有请求都不需要cookie时,我们有三种方式:
将HTTPCookieStorage设为nil
这样cookie将无处安放,也就没有cookie;
将HTTPCookieAcceptPolicy设为NSHTTPCookieAcceptPolicyNever
客户端不接受服务器发来的cookie
HTTPShouldSetCookies设为NO
发送请求时不带cookie
HTTPShouldHandleCookies为NO
如果单个请求想不带cookie可以设置NSMutableURLRequest的HTTPShouldHandleCookies为NO。
4.1 cookie策略
影响整个session cache行为的是NSURLSessionConfiguration的requestCachePolicy属性。
而影响整个session cookie行为的是NSURLSession的HTTPCookieAcceptPolicy属性和HTTPShouldSetCookies的开关。
这两个属性的不同是:
HTTPCookieAcceptPolicy策略决定客户端何时存储服务器发送来的cookie;
HTTPShouldSetCookies决定客户端发送请求时带不带cookie。
NSMutableURLRequest只有HTTPShouldHandleCookies这个开关来决定是否带cookie请求。
作为一个请求,它没法决定是否存储cookie。
4.2 NSHTTPCookieAcceptPolicy
HTTPCookieAcceptPolicy有如下三中策略: NSHTTPCookieAcceptPolicyAlways 接受所有cookie NSHTTPCookieAcceptPolicyNever 从来不接受cookie NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain 这个是默认值,只会对主域名的Cookie进行缓存,子域名或者请求资源的相关cookie并不会缓存。 在NSURLConfiguration中说明HTTPCookieAcceptPolicy的默认值是NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain。
而在NSHTTPCookieAcceptPolicy枚举中说明默认的枚举类型是NSHTTPCookieAcceptPolicyAlways。
测试发现其默认枚举类型是NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain。
4.3 HTTPShouldSetCookies与HTTPShouldHandleCookies
HTTPShouldSetCookies与HTTPShouldHandleCookies这一对开关影响请求是否使用cookie。
HTTPShouldSetCookies是NSURLSession中的属性,HTTPShouldHandleCookies是NSURLRequest的属性。
与cache类似,HTTPShouldHandleCookies的优先级更高。
当HTTPShouldHandleCookies手动设置为YESE时,请求时必定会带上本地的cookie。注意是手动改为YES,如果保持默认值不变系统就会以NSURLSession的HTTPShouldSetCookies为准。
HTTPShouldHandleCookies默认值也是YES。
HTTPShouldSetCookies设置为NO时,所有通过该session的请求,在不修改HTTPShouldHandleCookies默认值的情况下都不会带有cookie。
如果想带有cookie,需要手动设置请求header中的cookie。
5.app使用cookie流程
1).对于会话cookie的话
因为程序kill掉会自动清除,所以想要下次还保留就需要设置过期时间和sessionOnly,或者 自己手动保存cookie (参考本地化cookie).然后在启动app的时候,把本地的cookie取出来设置进 去. ,然后下次请求的时候都会带上cookie.
2).使用 AFNetworking 时,Cookies
如果HTTPShouldHandkeCookies 设置为YES,代表自动AFNetworking自动管理cookie, 就是后台返回cookie,会自动设置到NSHTTPCookieStorage这个类里面 ,让每次请求的时候回带上cookie. (一般我们都是自动管理)
如果不想自动管理 ,请设置为NO,然后cookie自己手动管理,每次请求设置上Cookie
5)WKWebView和Cookie
 WKWebView 发起的请求不会自动带上存储于 NSHTTPCookieStorage 容器中的 Cookie
目前许多 H5 业务都依赖于 Cookie 作登录态校验,如果登陆是在 WebView 里做的,不会有什么问题;但是在很多场景下,在Native做登录,需要将登录信息带给WebView;但是在Native做了登录,也获取了Cookie信息,也使用 NSHTTPCookieStorage 将Cookie存到了本地;但是WKWebView在打开时候,不会自动去NSHTTPCookieStorage获取Cookie信息,这就是著名的首次 WKWebView 请求不携带 Cookie 的问题。
WKWebView 实例其实会将 Cookie 存储于 NSHTTPCookieStorage 中,但存储时机有延迟,在iOS 8上,当页面跳转的时候,当前页面的 Cookie 会写入 NSHTTPCookieStorage 中,而在 iOS 10 上,JS 执行 document.cookie 或服务器 set-cookie 注入的 Cookie 会很快同步到 NSHTTPCookieStorage 中。
其实,iOS11 可以解决首次 WKWebView 请求不携带 Cookie 的问题,只要是存在 WKHTTPCookieStore 里的 cookie,WKWebView 每次请求都会携带。
6).WKWebView的Cookie注入 在初始化 WKWebView 的时候,通过 WKUserScript 设置,使用Javascript 注入 Cookie
6).1 NSMutableURLRequest 请求带上 Cookie
6).2 WKHTTPCookieStore (iOS 11 later)
利用iOS11 API WKHTTPCookieStore 解决 WKWebView 首次请求不携带 Cookie 的问题;这是因为:WKWebView每次请求都会携带 WKHTTPCookieStore 里的 Cookie。(WKWebView 使用 NSURLProtocol 拦截请求无法获取 Cookie 信息) 在执行 [WKWebView loadRequest:] 前将 NSHTTPCookieStorage中的Cookie信息复制到 WKHTTPCookieStore 中,以此来达到 WKWebView中注入Cookie 的目的
6).3多WKWebView实例共享Cookie
Session 级别的 cookie 是保存在 WKProcessPool 里的,每个 WKWebview 都可以关联一个 WKProcessPool 的实例,如果需要在整个 App 生命周期里访问 h5 保留 h5 里的登录状态的,可以将使用 WKProcessPool 的单例来共享登录状态。
让所有 WKWebView 共享同一个 WKProcessPool 实例,可以实现多个 WKWebView 之间共享 Cookie(session Cookie and persistent Cookie) 数据。不过 WKWebView WKProcessPool 实例在 App 杀进程重启后会被重置,导致 WKProcessPool 中的 Cookie、session Cookie 数据丢失,目前也无法实现 WKProcessPool 实例本地化保存。