入门 HTTP 协议

《图解 HTTP》读书笔记

通信模型

HTTP 协议被用于客户端和服务器之间的通信,请求访问文本或者图片等资源的一端称为客户端,而提供资源响应的一端称为服务器端。


客户端和服务器模型

在 HTTP 中规定,请求从客户端发出,服务器收到请求并响应后返回。HTTP 是一种无状态(stateless)协议, HTTP 协议自身不对请求和响应之间的通信状态进行保存,也就是说不对发送过的请求或者响应做持久化处理。但是随着技术发展,无状态的 HTTP 协议很难满足业务需要,比如用户登陆到一个网站之后,在这个网站的不同页面跳转的时候需要继续保持用户的登陆状态。网站为了能够掌握是哪个客户端发出的请求,需要保存用户的状态。HTTP 为了实现保持状态的功能,引入了我们熟知的 Cookie 技术来实现状态管理。

HTTP 请求

HTTP 的 GET 方法

GET 方法用来请求访问资源。如果请求的资源是文本,那么文本就保持原样返回。如果请求的资源是 CGI 程序(Common Gateway Interface,通用网关接口),那么服务端返回经过执行后的输出结果。

使用 GET 方法的请求,请求 index.html 的页面资源


image.png

使用 GET 方法的响应,返回 index.html 的页面资源


image.png

HTTP 的 POST 方法

POST 方法通常用来提交数据给服务端。虽然 GET 方法也可以用来提交数据,但一般并不使用 GET 方法。值得一提的是,GET 方法的参数会以 QueryString 的形式跟在请求链接后面而 POST 方法不会,但是不管 HTTP 的 GET 方法还是 POST 方法都是不安全的,请求数据都会被拦截。

HTTP 的报文结构

HTTP 通行过程包括从客户端发起请求和服务端响应请求的过程。用于 HTTP 协议交互的信息称为 HTTP 报文,客户端的 HTTP 报文称为请求报文,服务端的报文叫做响应报文。HTTP 报文本身是由多行数据构成的字符串文件。HTTP 报文大概可以分为 2 块,一块是报文首部,一块是报文主体,2 者之间使用空行来划分。通常情况下,报文主体不一定存在。

请求报文和响应报文

请求报文和响应报文的首部内容由以下数据组成。

  1. 请求行, 包括请求的方法,请求 URI 和 HTTP 版本
  2. 状态行,表示响应结果的状态码,原因短语和 HTTP 版本
  3. 首部字段,表示请求和响应的各种条件,属性的各类首部。一般有 4 种首付,分别是通用首部,请求首部,响应首部和实体首部
  4. 其他

我们使用 GET 方法请求 http://hackr.jp/index.htm 链接,请求报文和响应报文如

请求报文

响应报文

HTTP 提升传输效率

HTTP 在传输数据时既可以按照数据原貌直接传输,也可以在传输过程中通过编码来提升传输效率。为了让 HTTP 报文的数据容量尽可能的小,HTTP 协议规定了一个内容编码的功能用于压缩数据。举个例子,客户端请求的内容编码说明了数据的编码格式,HTTP协议按照编码格式对数据内容进行编码并传输,服务端接收数据后,HTTP 协议按照对应的编码格式对数据进行解码。常见的内容编码格式有 gzip,compress,deflate,identity。

内容编码传输

HTTP 分块传输编码

在 HTTP 通信过程中,请求的编码实体资源未全部完成传输之前,浏览器无法显示资源。所以设计人员设计了一个功能,叫做分块传输编码 (Chunked Transfer Coding)

image.png

分块传输编码会将实体主体分成多个部分。每一块都会用十六进制来标记块的大小,而实体主体的最后一块会使用“ 0(CR+LF)”来标记。使用分块传输编码的实体主体会由接收的客户端来负责解码,恢复到编码前的实体主体。

HTTP 的 Multipart

HTTP 协议中规定,发送的一份报文主体内可以包含多种类型实体(Multipart),比如文本,视频,图片。通常在图片或者文本文件上传的时候会使用到这个功能。在 HTTP 报文中使用 Multipart 的时候需要在首部字段里面加上 Content-Type,使用 boundary 来划分不同的实体。在不同的实体的起始行前插入 “--” 标记,而在 Multipart 的最后部分插入 “--” 标记,如下图所示的 --AaB03x,--AaB03x--。

使用 Multipart/form-data 上传表单

“Content-Type: multipart/form-data; boundary=AaB03x
 
--AaB03x
Content-Disposition: form-data; name="field1"
 
Joe Blow
--AaB03x
Content-Disposition: form-data; name="pics"; filename="file1.txt"
Content-Type: text/plain
 
...(file1.txt的数据)...
--AaB03x--”

使用 Multipart/byteranges 响应,状态码 206。该报文可以在需要响应多个范围的内容时使用。在不同的实体的起始行前插入 “--” 标记,而在 Multipart 的最后部分插入 “--” 标记,如下图所示的 --THIS_STRING_SEPARATES,--THIS_STRING_SEPARATES--。

“HTTP/1.1 206 Partial Content
Date: Fri, 13 Jul 2012 02:45:26 GMT
Last-Modified: Fri, 31 Aug 2007 02:02:20 GMT
Content-Type: multipart/byteranges; boundary=THIS_STRING_SEPARATES


--THIS_STRING_SEPARATES
Content-Type: application/pdf
Content-Range: bytes 500-999/8000
...(范围指定的数据)...

--THIS_STRING_SEPARATES
Content-Type: application/pdf”
“Content-Range: bytes 7000-7999/8000
...(范围指定的数据)...

--THIS_STRING_SEPARATES--”

HTTP 的 范围请求 (Range Request)

HTTP 协议设计了这么一个功能,用户下载大图片过程中,若是遇到网络中断的情况,在网络恢复之后,可以从之前下载中断处恢复。这种指定范围发送的请求叫做范围请求 (Range Request),通常可以使用这个特性来做断点下载功能。

对于一份 10 000 字节大小的资源,可以使用 Range Request 只请求 5001 ~ 10 000 字节内的资源。


image.png

请求 5001 ~ 10 000 字节,使用首部字段 Range 来指定资源的范围

Range:bytes=5001-10000

从 5000 字节之后的全部范围

Range:bytes=5001-

也可以指定多重范围

Range:bytes=-3000,5000-7000

对于范围请求 (Range Request),响应会返回状态码 206 的响应报文,使用 Content-Range 来标明响应范围。值的一提的是,若是服务端无法响应范围请求,那么服务端则会返回状态码 200 OK 和 完整的实体内容。
对于多重范围的范围请求,响应报文会在首部字段 Content-Type 标明 multipart/byteranges 后返回响应报文,如下所示。

“HTTP/1.1 206 Partial Content
Date: Fri, 13 Jul 2012 02:45:26 GMT
Last-Modified: Fri, 31 Aug 2007 02:02:20 GMT
Content-Type: multipart/byteranges; boundary=THIS_STRING_SEPARATES


--THIS_STRING_SEPARATES
Content-Type: application/pdf
Content-Range: bytes 500-999/8000
...(范围指定的数据)...

--THIS_STRING_SEPARATES
Content-Type: application/pdf”
“Content-Range: bytes 7000-7999/8000
...(范围指定的数据)...

--THIS_STRING_SEPARATES--”

HTTP 状态码

HTTP 状态码的职责是当客户端向服务器发送请求是,描述返回的请求结果。利用状态码,客户端可以知道服务端是否正常处理了请求。


image.png
  1. 1XX,表示接收的请求正在处理
  2. 2XX,请求正常处理完毕
  3. 3XX,需要附加操作才能完成请求,也就是重定向
  4. 4XX,服务器无法处理请求,也就是客户端错误
  5. 5XX,服务器处理请求出错,也就是服务器错误

200 OK,表示客户端发来的请求在服务端被正常处理了


image.png

204 No Content,表示客户端发来的请求在服务端被成功处理,但是响应内容中不返回实体的主体部分


image.png

206 Partial Content,表示客户端发来的范围请求被服务端处理了,响应报文中包含由 Content-Range 指定范围的实体内容


image.png

301 Moved Permanently,表示客户端请求的资源已经被永久分配了新的
URI,以后使用资源的话要用新的 URI

image.png

302 Found,表示客户端请求的资源已经被分配了新的 URI,这次临时使用这个新的 URI

image.png

303 See Other,表示客户端请求对应的资源存在着另一个 URI,应使用 GET 方法定向获取请求的资源


image.png

304 Not Modified,表示客户端请求对应的资源若是有发生变化,则响应资源,若是没有发生变化,响应时不包含任何响应的主体部分


image.png

400 Bad Request,表示客户端的请求报文中存在语法错误


image.png

401 Unauthorized,表示客户端发送的请求需要有通过 HTTP 认证的认证信息


image.png

403 Forbidden,表示客户端对资源的访问请求被拒绝了,未获得访问授权可能是发生 403 的原因


image.png

404 Not Found,表示服务端上面无法找到请求的资源,客户端的 URI 错误可能是发生 404 的原因


image.png

500 Internal Server Error,表示服务端在执行请求的时候发生了错误。


image.png

503 Service Unavailable,表示服务器处于超负载或者停机维护,现在无法处理请求。


image.png

HTTP 首部字段

HTTP 首部字段根据实际用途可以分为 4 个类型,这些首部字段只需了解常见的类型,其他类型遇到的时候可以自行搜索即可。

  1. 通用首部字段,请求和响应报文都会使用的首部
  2. 请求首部字段,从客户端向服务器发送请求时使用的首部
  3. 响应首部字段,从服务端向客户端返回响应报文时使用的首部
  4. 实体首部字段,针对请求和响应报文的实体部分使用的首部
通用首部字段名 说明
Cache-Control 控制缓存的行为
Connection 逐跳首部、连接的管理
Date 创建报文的日期时间
Pragma 报文指令
Trailer 报文末端的首部一览
Transfer-Encoding 指定报文主体的传输编码方式
Upgrade 升级为其他协议
Via 代理服务器的相关信息
Warning 错误通知
请求首部字段名 说明
Accept 用户代理可处理的媒体类型
Accept-Charset 优先的字符集
Accept-Encoding 优先的内容编码
Accept-Language 优先的语言(自然语言)
Authorization Web认证信息
Expect 期待服务器的特定行为
From 用户的电子邮箱地址
Host 请求资源所在服务器
If-Match 比较实体标记(ETag)
If-Modified-Since 比较资源的更新时间
If-None-Match 比较实体标记(与 If-Match 相反)
If-Range 资源未更新时发送实体 Byte 的范围请求
If-Unmodified-Since 比较资源的更新时间(与If-Modified-Since相反)
Max-Forwards 最大传输逐跳数
Proxy-Authorization 代理服务器要求客户端的认证信息
Range 实体的字节范围请求
Referer 对请求中 URI 的原始获取方
TE 传输编码的优先级
User-Agent HTTP 客户端程序的信息
响应首部字段名 说明
Accept-Ranges 是否接受字节范围请求
Age 推算资源创建经过时间
ETag 资源的匹配信息
Location 令客户端重定向至指定URI
Proxy-Authenticate 代理服务器对客户端的认证信息
Retry-After 对再次发起请求的时机要求
Server HTTP服务器的安装信息
Vary 代理服务器缓存的管理信息
WWW-Authenticate 服务器对客户端的认证信息
实体首部字段名 说明
Allow 资源可支持的HTTP方法
Content-Encoding 实体主体适用的编码方式
Content-Language 实体主体的自然语言
Content-Length 实体主体的大小(单位:字节)
Content-Location 替代对应资源的URI
Content-MD5 实体主体的报文摘要
Content-Range 实体主体的位置范围
Content-Type 实体主体的媒体类型
Expires 实体主体过期的日期时间
Last-Modified 资源的最后修改日期时间
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容