HTTP 的全称是 HyperText Transfer Protocol (超文本传输协议)的缩写,是一种创建在 TCP 上的无状态链接。HTTP 是互联网的基础协议,用于客户端与服务器之间的通讯,它规定了客户端和服务器之间的通讯格式,包括请求与响应的格式。html
基本的工做流程是客户端发送一个 HTTP 请求,服务端收到请求开始处理,处理结束返回给客户端结果,客户端对结果进行处理并展现。node
如今最流行的 HTTP 版本仍是 1997 年发布的 HTTP/1.1。 git
客户端向服务端发送一段请求报文,服务端收到后,返回响应报文,客户端对响应内容进行展现。github
一个 HTTP 的请求一定是由客户端发起,服务器端回复响应。服务器在没有接收到请求以前不会发送响应。web
名词解释算法
客户端:请求访问文本或图像等资源的一端。json
服务端:提供资源响应的一端。api
资源:网络上的一切内容都是资源,不管是图片文字仍是动态代码。浏览器
请求过程以下 ⬇️缓存
请求过程以下 ⬇️
报文是在 HTTP 应用程序之间发送的数据块。这些数据块以一些文本的元信息 (meta 标签中的信息) 开头,描述了报文的内容及含义。
每条报文都包含一条来自于客户端的请求,或者一条来自于服务端的响应。
它由 3 部分组成:对报文进行描述的「起始行」、包含属性的「首部(Header)」以及可选的、包含数据的「主体(body)」
<method> <path> <HTTP version>
<headers>
<entity-body>
复制代码
(注意,只有起始行的语法与请求报文有所不一样)
<HTTP version> <status code> <reason-phrase>
<headers>
<entity-body>
复制代码
下面是对各部分的简要描述,后面会详细介绍。
最多见的请求方法就是 GET
和 POST
了。除此以外还有 PUT
、DELETE
、HEAD
等。
GET /users/1 HTTP/1.1
Host: api.github.com
复制代码
对应的 Retrofit 的代码:
@GET("/users/{id}")
Call<User> getUser(@Path("id") String id, @Query("gender") String gender);
复制代码
POST /users HTTP/1.1
Host: api.github.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 13
复制代码
对应的 Retrofit 的代码:
@FormUrlEncoded
@POST("/users")
Call<User> addUser(@Field("name") String name, @Field("gender") String
gender);
复制代码
PUT /users/1 HTTP/1.1
Host: api.github.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 13
复制代码
对应的 Retrofit 的代码:
@FormUrlEncoded
@PUT("/users/{id}")
Call<User> updateGender(@Path("id") String id, @Field("gender") String
gender);
复制代码
DELETE /users/1 HTTP/1.1
Host: api.github.com
复制代码
对应的 Retrofit 的代码:
@DELETE("/users/{id}")
Call<User> getUser(@Path("id") String id, @Query("gender") String gender);
复制代码
HEAD
与 GET
的使用方式彻底相同。HEAD
请求的返回响应中没有 Body
GET
、PUT
、DELETE
都是幂等操做,就是说,请求一次和请求屡次的结果是同样的。 好比,GET 请求一个数据,请求一次和请求十次返回的结果是同样的,PUT 一样修改一个数据,修改一次和修改十次,结果也都是同样的。
状态码是对结果进行类型化的描述的,好比「请求成功」、「内容未找到」等 主要分为 5 类。
100:继续发送
101:正在切换协议
复制代码
200:OK (最多见)
201:建立成功
复制代码
301:域名永久移动
302:暂时移动
304:内容未改变,请求被重定向到客户端本地缓存
复制代码
400:客户端请求错误,服务器不理解请求的语法。
401:未受权,要求进行身份验证。
403:被禁止,服务器拒绝请求。
404:找不到内容,服务器找不到请求的网页。(最多见)
复制代码
500:服务器内部错误 (最多见)
503:服务不可用
复制代码
首部包含多个请求头,是用来描述消息的元数据(meta data)。
首部字段有不少,主要分为如下几类:
下面咱们就说一些比较经常使用的。
提供日期和时间标志,说明报文是在什么时间建立的。
Date: Tue, 12 Feb 2019 07:32:07 GMT
复制代码
容许客户端和服务器指定与请求/响应链接有关的选项。
Connection: keep-alive
复制代码
Via : 显示报文通过的中间节点(代理、网关)。
via: cache25.l2ot7-1[0,304-0,H], cache25.l2ot7-1[1,0], cache5.us14[342,200-0,H]
复制代码
Transfer-Encoding : 告知接收端为了保证报文的可靠传输,对报文采用了什么编码方式。
Transfer-Encoding: chunked
复制代码
Cache-Control : 指定缓存的控制方式。
cache-control: no-store, no-cache, must-revalidate, proxy-revalidate
复制代码
给出了接收请求的服务器的主机名和端口。(注意:不是在网络上用于寻址的,⽽是在目标服务器上定位子服务器。)
Host: api.github.com
复制代码
用来告诉服务端客户端会接受的媒体类型,包括客户端须要什么,可使用什么,以及不想要什么。
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
'*' 用来表示通配符。
;q= (q-factor weighting)
值表明优先顺序,用相对质量价值表示,又称为权重。
复制代码
用来告知服务器,客户端能够处理的字符集类型。
Accept-Charset: utf-8, iso-8859-1;q=0.5
复制代码
用来将客户端可以理解的内容编码方式告知服务器,服务端会选择一个客户端提议的方式。
Accept-Encoding: gzip, deflate, br
gzip:表示采用 Lempel-Ziv coding (LZ77) 压缩算法,以及32位CRC校验的编码方式。
compress:采用 Lempel-Ziv-Welch (LZW) 压缩算法。
deflate:采用 zlib 结构和 deflate 压缩算法。
br:表示采用 Brotli 算法的编码方式。
identity:用于指代自身(例如:未通过压缩和修改)。除非特别指明,这个标记始终能够被接受。
复制代码
用来告诉服务器,客户端可以理解哪些语言
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
复制代码
告诉服务器,客户端要获取哪段数据。 主要用于:断点续传、多线程下载。
语法:
Range: <unit>=<range-start>-<range-end>, <range-start>-<range-end>, <range-start>-<range-end>
<unit>:范围所采用的单位,一般是字节(bytes)。
<range-start>:一个整数,表示在特定单位下,范围的起始值。
<range-end>:一个整数,表示在特定单位下,范围的结束值。这个值是可选的,若是不存在,表示此范围一直延伸到文档结束。
Range: bytes=200-1000, 2000-6576, 19000-
复制代码
提供了客户端用户的 E-mail 地址, 用处:好比你有一个爬虫程序,那么 Form 首部应该随请求一块儿发送,这样的话,在服务器遇到问题的时候,例如爬虫发送了过量的、不但愿收到的或者不合法的请求时,站点管理员能够联系到你。
包含了处理请求的源头服务器所用到的软件相关信息
Server: Apache-Coyote/1.1
复制代码
用来由服务器端向客户端发送 cookie。
会话期 cookies 将会在客户端关闭时被移除。
会话期 cookie 不设置 Expires 或 Max-Age 指令
Set-Cookie: sessionid=38afes7a8; HttpOnly; Path=/
持久化 Cookie 不会在客户端关闭时失效,而是在特定的日期(Expires)或者通过一段特定的时间以后(Max-Age)才会失效。
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly
复制代码
响应中出现,表示服务器支持按字节来取范围数据
语法:
Accept-Ranges: bytes
Accept-Ranges: none
none:不支持任何范围请求单位,因为其等同于没有返回此头部,所以不多使用。
bytes:范围请求的单位是 bytes (字节)。
Accept-Ranges: bytes
复制代码
因为请求与响应中均可以包含 body部分,因此在请求报文与响应报文中均可以出现这部分字段。
指定的是须要将页面从新定向至的地址。通常在响应码为 3xx 的响应中才会有意义。
Location: /index.html
复制代码
告诉客户端实际返回的内容的内容类型。 主要分为 4 类。
请求 Web ⻚面时返回响应的类型,Body 中返回 html 文本。
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 853
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
复制代码
Web ⻚面纯⽂本表单的提交方式
POST /users HTTP/1.1
Host: api.github.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 27
name=xxtlant&gender=male
复制代码
Web ⻚面含有⼆制⽂件时的提交方式。
POST /users HTTP/1.1
Host: hencoder.com
Content-Type: multipart/form-data; boundary=----
WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Length: 2382
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="name"
rengwuxian
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="avatar"; filename="avatar.jpg"
Content-Type: image/jpeg
JFIFHHvOwX9jximQrWa......
------WebKitFormBoundary7MA4YWxkTrZu0gW--
复制代码
单项内容(⽂本或非⽂本均可以),用于 Web Api 的响应或者 POST / PUT 的请求。
请求中提交 JSON
POST /users HTTP/1.1
Host: api.github.com
Content-Type: application/json; charset=utf-8
Content-Length: 38
{"name":"xxtlant","gender":"male"}
复制代码
响应中返回 JSON
Date: Tue, 12 Feb 2019 08:04:14 GMT
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
Server: GitHub.com
Status: 200 OK
{"login": "xxtlant",
"id": 18342980,
"node_id": "MDQ6VXNlcjE4MzQyOTgw",
"avatar_url": "https://avatars2.githubusercontent.com/u/18342980?v=4",
"gravatar_id": "",
....
复制代码
请求中提交⼆进制内容
POST /user/1/avatar HTTP/1.1
Host: hencoder.com
Content-Type: image/jpeg
Content-Length: 1575
JFIFHH9......
复制代码
相应中返回⼆进制内容
HTTP/1.1 200 OK
content-type: image/jpeg
content-length: 1575
JFIFHH9......
复制代码
用来指明发送给接收方的消息主体的大小。
Content-Length: <length>
复制代码
用于对特定媒体类型的数据进行压缩。 这个消息用来告知客户端应该怎样解码才能获取在 Content-Type 中的媒体类型内容。
Content-Encoding: gzip
其值受 Accept-Encoding 影响
复制代码
与此对应,Content-Language 也与 Accept-Language 对应。