截屏2022-09-07 09.48.16.pngcookie:HTTP Cookie是服务器发送到客户端并保存在本地的一小块数据,它会在客户端下一次向同一服务器再发起请求时被携带并发送到服务器上,以此来维护弥补HTTP协议无状态的不足。在Session出现之前,基本上所有的网站都采用Cookie来跟踪会话。
截屏2022-09-07 09.15.10.png
一、Cookies的生成
Cookies第一次由服务器生成并返回给客户端
mport PerfectHTTP
import PerfectHTTPServer
import Foundation
var routes = Routes()
routes.add(method: .post, uri: "/login") { request, response in
let cookis = HTTPCookie.init(name: "aa", value: "zxcvvffgggg", domain:nil, expires:.relativeSeconds(10000), path: "/", secure: false, httpOnly: false, sameSite: nil)
response.addCookie(cookis)
response.completed()
}
try HTTPServer.launch(name: "localhost",
port: 8181,
routes: routes,
responseFilters: [
(PerfectHTTPServer.HTTPFilter.contentCompression(data: [:]), HTTPFilterPriority.high)])
正如上面一个login接口,服务器生成了cookies并返回客户端。客户端可以通过responseHeader看到携带过来的cookies
"Set-Cookie" = (
"aa=zxcvvffgggg;expires=Wed, 07-Sep-2022 04:51:58 GMT; path=/"
);
二、iOS中的Cookies
我们开发时用UrlSession发送一个网络请求时,可能不会太在意cookies,但并不能说明ios中没有cookies。底层的网络层也会自动的为我们管理cookie:从response中解析cookie缓存和从缓存自动取出对应cookie填充到UrlRequest对象中。
直接打印 print(task.currentRequest!.allHTTPHeaderFields)是看不到的,但并不意味着UrlSession再次访问请求时/m y,并不有自动携带cookies,在服务端是看到的
routes.add(method: .post, uri: "/my") { request, response in
print(request.header(.cookie)!)
response.completed()
}
截屏2022-09-07 13.05.54.png
NSHTTPCookieStorage
NSHTTPCookieStorage 实现了一个管理cookie的单例对象(只有一个实例),每个Cookie都是NSHTTPCookie类的实例,作为为一个规则,Cookie在(macOS)所有应用之间共享并在不同进程之间保持同步,在iOS中不会多应用共享。Session Cookie(一个isSessionOnly方法返回YES的Cookie)只能在单一进程中使用。
let cookiestorge = HTTPCookieStorage.shared
let cookies:[HTTPCookie]? = cookiestorge.cookies
print(cookies!)
截屏2022-09-07 13.40.10.png
可见cookies真的是存在app本地了
- 当sessionOnly为true时,关闭app后cookies就不会被保存到本地;当sessionOnly为false时,关闭app后cookies会存在本地;sessionOnly属性这个值主要由后台服务器决定
URLSession的configuration
-
defaultSessionConfiguration:使用基于硬盘的持久化Cache,保存用户的证书到钥匙串,使用共享cookie存储
-
emhemeralSessionConfiguration配置信息和default大致相同。除了不会把cache、证书或者任何和Session相关的数据存储到硬盘,而是存储在内存中,生命周期和Session一致。比如浏览器无痕浏览等功能就可以基于这个来做。
-
backgroundSessionConfigurationWithIdentifier:(NSString )identifier创建一个可以在后台甚至APP已经关闭的时候仍然传输数据的会话。注意,后台Session一定要在创建的时候赋予一个唯一的identifier,这样在APP下次运行的时候,能够根据identifier来进行相关的区分。如果用户关闭了APP,iOS系统会关闭所有的background Session。而且被用户强制关闭了以后,iOS系统不会主动唤醒APP,只有用户下次启动了APP,数据传输才会传输。
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let cookiestorge = HTTPCookieStorage.shared
let cookies:[HTTPCookie]? = cookiestorge.cookies
print(cookies!)
let urlString = "http://localhost:8181//login"
var request = URLRequest(url: URL(string: urlString)!)
request.httpMethod = "POST"
let str = "d=444&e=111"
let normaldata = str.data(using: .utf8)
let dic = ["d":1,"e":11]
let data = try! JSONSerialization.data(withJSONObject:dic , options: .fragmentsAllowed)
request.httpBody = normaldata
let session = URLSession(configuration: .ephemeral, delegate: self, delegateQueue: nil)
session.dataTask(with: request).resume()
}
总结
当URLSession的configuration 是 .ephemeral时,cookies根本是不会被保存到本地的; 当URLSession的configuration 是 .defaultl时,cookie在app没关闭时肯定是保存到本地的,cookie在关闭后会不会保存到本地就看sessionOnly的ture还是false了
网友评论