WKWebView之cookie分析

WKWebView中cookie方案。
在http超文本传输应用层协议中Cookie是非常重要的角色。http是无状态协议不具有记录状态的特性即http不会记录之前的访问情况来处理下次请求,在很多涉及账号的网页中,页面需要根据是否已登录的状态来显示不同内容。为了避免每次访问都要重复登录,可以在第一次登录完成后将登录信息写入cookie保存,添加到之后的其他请求中,补充解决http不能记录状态的问题。从开发者层面说,cookie本质是包含了一系列key-value对的数组(外层为数组元素为词典(次级key-value对))。
WKWebView之cookie分析
客户端第一次向服务器发送请求的时候,没有cookie,服务器收到后,会生成可以表示客户端身份的cookie,服务器将cookie封装到响应包的头部的set-cookie字段,返回给客户端,客户端根据set-cookie的内容设置cookie,并在之后的请求中带上cookie内容,这样服务器就能识别到这个客户端了。
关于WKWebView
本文对WKWebView中的cookie问题做出一些总结,不会详细说明WKWebView的API的协议的使用。WKWebView是在iOS8后UIWebView替代品,具有低内存(实际是开启另外进程),与Safari具有相同的JavaScript引擎,高效的app与web的通信数据转移(注入JavaScript脚本,messageHandler回调JavaScript方法)等。
Starting in iOS 8.0 and OS X 10.10, use WKWebView to add web content to your app. Do not use UIWebView or WebView.在iOS8后,建议使用WKWebView,但是使用过程中有很多坑,具体请看WKWebView那些坑。
关于WKWebView那些坑
在UIWebView中,在每次请求之前,会讲NSHTTPCookieStorage里的cookie自动添加到请求中,因此UIWebView上的cookie问题并不突出。然而经过测试发现,WKWebView中并不会自动向请求中添加cookie:
WKWebView Cookie 问题在于 WKWebView 发起的请求不会自动带上存储于 NSHTTPCookieStorage 容器中的 Cookie。
实践发现 WKWebView 实例其实也会将 Cookie 存储于 NSHTTPCookieStorage 中,但存储时机有延迟,在iOS 8上,当页面跳转的时候,当前页面的 Cookie 会写入 NSHTTPCookieStorage 中,而在 iOS 10 上,JS 执行 document.cookie 或服务器 set-cookie 注入的 Cookie 会很快同步到 NSHTTPCookieStorage 中
WKWebView中cookie的解决方案有:
方案1:WKWebView loadRequest 前,在 request header 中设置 Cookie, 解决首个请求 Cookie 带不上的问题;
缺陷:只能解决指定的一个URL的请求,涉及到同域的Ajax跳转还是会缺失cookie
方案2: 通过 document.cookie 设置 Cookie 解决后续页面(同域)Ajax、iframe 请求的 Cookie 问题;
缺陷:不能解决跨域cookie的问题
方案3:每次页面跳转的时候回调用decidePolicyForNavigationAction回调,那么就可以在回调里拦截请求,加入cookie后重新发送。
缺陷:loadRequest是加载mainFrame请求,所以依然解决不了页面 iframe 跨域请求的 Cookie 问题