一、HTTP协议是什么?
-
HTTP(Hyper Text Transfer Protocol)
译为超文本传输协议,是一种应用层协议
,如下图所示,目前有HTTP1.0、HTTP2.0、HTTP3.0
三个版本,HTTP3.0
也叫HTTP over QUIC
-
2.HTTP的标准由
万维网协会(W3C)、互联网工程任务组(IETF)
协调制定,最终发布了一系列的RFC(RFC全称是Request For Comments
,可以译为:请求意见稿 )-
- HTTP的历史如下所示:
◼ 1996年,
HTTP/1.0
发布,HTTP1.0支持POST、HEAD
等请求方法,支持请求头、响应头等,支持更多种数据类型(不再局限于文本数据) ,浏览器的每次请求都需要与服务器建立一个TCP连接,请求处理完成后立即断开TCP连接◼ 1997年,
HTTP/1.1
发布(最经典、使用最广泛的版本) ,支持PUT、DELETE
等请求方法,采用持久连接(Connection: keep-alive)
,多个请求可以共用同一个TCP连接
◼ 2015年5月,
HTTP/2.0标准
以RFC 7540
正式发表,HTTP/2.0
增加了二进制传输、多路复用、头部压缩、服务器推送、优先级
等特性◼ 2022年6月6日,IETF QUIC和HTTP工作组成员Robin Mark在推特上宣布,历时5年,
HTTP/3
终于被标准化为 RFC 9114,这是HTTP超文本传输协议的第三个主要版本
二、HTTP协议的报文格式
- 其中,
start-line
代表是请求行或者响应行,header-filed
代表请求头或者响应头,*
代表0个或多个,CRLF
代表换行,messgae-body
代表请求体或者响应体,想了解start-line、header-field
的具体格式,可以去RFC7230查看
- 其中,
- 举一个例子,来说明一下HTTP的报文格式,如下所示,第一行是一个
start-line
,后面是多个header-field
,接下来是CRLF
,这里没有message-body
- 举一个例子,来说明一下HTTP的报文格式,如下所示,第一行是一个
三、HTTP的请求方法和字段
-
-
start-line
中需要明确HTTP的请求方法,在RFC 7231, section 4: Request methods中描述了8种请求方法,分别是GET、HEAD、POST、PUT、DELETE、CONNECT、OPTIONS、TRACE
,这些请求方法的含义如下所示:
◼ GET:常用于读取的操作,请求参数直接拼接在URL的后面(浏览器对URL是有长度限制的)
◼ POST:常用于添加、修改、删除的操作,请求参数可以放到请求体中(没有大小限制)
◼ HEAD:请求得到与GET请求相同的响应,但没有响应体
使用场景举例:在下载一个大文件前,先获取其大小,再决定是否要下载。以此可以节约带宽资源◼ DELETE:用于删除指定的资源
◼ TRACE:请求服务器回显其收到的请求信息,主要用于HTTP请求的测试或诊断
◼ CONNECT:可以开启一个客户端与所请求资源之间的双向沟通的通道,它可以用来创建隧道(tunnel) ,可以用来访问采用了 SSL (HTTPS) 协议的站点
-
-
header-filed
头部字段有四种类型,主要就是描述请求/响应的信息,具体每个字段的含义,可以去这里查询HTTP/Headers,我们这里说需要注意的几个字段,如下所示:
-
-
- HTTP 的
Cookie
和Session
(1). 当客户端第一次请求服务器的时候,服务器生成一份
session
保存在服务端,该session的id就是cookie,服务器会返回Set-Cookie
的响应体给客户端,让客户端存储cookie,这样以后客户端只需要在请求头中设置Cookie
字段,服务器就可以辨认出客户端的身份啦(2).cookie存储在客户端,session存储在服务器端,使用cookie可以帮助服务器辨别客户端,以便它们之间更好地通信
- HTTP 的
-
- HTTP 的
Content-Type
字段,可以让我们知道请求的内容是什么,进而用对应的方式解析,常见的Content-Type
有以下几种:
(1).
application/x-www-form-urlencoded
,HTTP会将请求参数用key1=val1&key2=val2的方式进行组织,并放到请求实体里面,注意如果是中文或特殊字符如"/"、","、“:" 等会自动进行URL转码。不支持文件,一般用于表单提交,例如html中的form标签,默认就采用application/x-www-form-urlencoded
-
(2).
multipart/form-data
,与application/x-www-form-urlencoded
不同,这是一个多部分多媒体类型,一般用于上传多个文件,首先生成了一个boundary
用于分割不同的字段,在请求实体里每个参数以------boundary
开始,然后是附加信息和参数名,然后是空行,最后是参数内容;多个参数将会有多个boundary块,如果参数是文件会有特别的文件域
最后以
------boundary--
为结束标识需要注意的是:上传文件的content-type必须使用
multipart/form-data
,如下所示:
- HTTP 的
NSString *boundary = @"PIUSDUFIASDFUPAUskfa";
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
[networkRequest setValue:contentType forHTTPHeaderField: @"Content-Type"];
- (3).
application/json
,JSON 是一种轻量级的数据格式,以“键-值”对
的方式组织的数据,需要注意的是,想用这种类型需要保证参数本身就是json格式的数据(因为参数会被直接放到请求体里,不会进行任何处理)
四、HTTP的缓存机制
1.HTTP有一大堆字段来控制缓存,例如
Pragma、Expires、Cache-Control、Last-Modified、ETag、If-None-Match、If-Modified-Since
,那么这些字段是如何工作的呢?我们先来了解下这些字段的含义,再来说整个控制流程-
首先是关于缓存控制的字段,优先级:
Pragma > Cache-Control > Expires
◼Pragma:作用类似于Cache-Control,HTTP/1.0的产物
◼Expires:缓存的过期时间(GMT格式时间),HTTP/1.0的产物
◼Cache-Control:设置缓存策略,有五个值可供选择,如下所示:
-
no-storage:不缓存数据到本地
public:允许用户、代理服务器缓存数据到本地
private:只允许用户缓存数据到本地
max-age:缓存的有效时间(多长时间不过期),单位秒
no-cache:每次需要发请求给服务器询问缓存是否有变化,再来决定如何使用缓存
-
- 然后是标识资源的字段,优先级:
ETag > Last-Modified
◼ Last-Modified:资源的最后一次修改时间
◼ ETag:资源的唯一标识(根据文件内容计算出来的摘要值)
- 然后是标识资源的字段,优先级:
4.
If-None-Match 和 If-Modified-Since
字段
◼ If-None-Match
,如果上一次的响应头中有ETag
,就会将ETag
的值作为请求头的值 ;如果服务器发现资源的最新摘要值跟If-None-Match
不匹配,就会返回新的资源(200 OK) ;否则,就不会返回资源的具体数据(304 Not Modified)
◼ If-Modified-Since
,如果上一次的响应头中没有ETag,有Last-Modified
,就会将Last-Modified的值作为请求头的值 ;如果服务器发现资源的最后一次修改时间晚于If-Modified-Since
,就会返回新的资源(200 OK) ;否则,就不会返回资源的具体数据(304 Not Modified)
- HTTP控制缓存的整个流程,如下图所示: