HTTP的概念、原理、工作机制、数据格式
HTTP 的定义
一种网络传输协议,位于 TCP/IP
协议族的最顶层——应用层(这句话后面的课会详细解释)。
两种最直观的印象:
- 浏览器地址栏输入地址,打开网页
- Android中发送网络请求,返回对应内容
HTTP
Hypertext Transfer Protocol
,超文本传输协议,和 HTML
(Hypertext Markup Language
超文本标记语⾔) 一起诞生,用于在网络上请求和传输 HTML
内容。
超文本,即「扩展型文本」,指的是 HTML
中可以有链向别的文本的链接(hyperlink
)。
HTTP 的工作方式
浏览器:
用户输入地址后回车或点击链接 -> 浏览器拼装 HTTP
报文并发送请求给服务器 -> 服务器处理请求后发送响应报文给浏览器 -> 浏览器解析响应报文并使用渲染引擎显示到界面
手机 App:
用户点击或界面自动触发联网需求 -> Android 代码调用拼装 HTTP 报文并发送请求到服务器 -> 服务器处理请求后发送响应报文给⼿机 -> Android 代码处理响应报文并作出相应处理(如储存数据、加⼯数据、显示数据到界面)
URL 和 HTTP 报文
URL 格式
三部分:协议类型、服务器地址(和端⼝号)、路径(Path)
协议类型://服务器地址[:端⼝号]路径
报文格式
只关心“状态行
HTTP/1.1 200 OK
”、“content-encoding:gzip
”
关键内容:Request method
、Response status code
、Headers
、Body
Request Method请求方法
GET
- 用于获取资源;请求没有
Body
- 对服务器数据不进行修改
- 不发送
Body
(Retrofit
中get
带body
会直接报错) - 是幂等的(多次调用与一次调用结果一样)对应
1
2GET /users/1 HTTP/1.1
Host:api.github.comRetrofit
的代码:1
2
Call<User> getUser(; String id, gender)
POST
- 用于增加或修改资源:请求有
Body
- 发送给服务器的内容写在Body里面
- 不具有幂等性(因为有新增的情况)对应
1
2
3
4
5POST /users HTTP/1.1
Host: api.github.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 13
name=rengwuxian&gender=maleRetrofifit
的代码:1
2
3
4
Call<User> addUser( String name, String
gender);
PUT
- 用于修改资源:请求有
Body
- 发送给服务器的内容写在
Body
里面 - 具有幂等性(只有修改的情况)对应
1
2
3
4
5PUT /users/1 HTTP/1.1
Host: api.github.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 13
gender=femaleRetrofifit
的代码:1
2
3
4
Call<User> updateGender( String id, String
gender);
DELETE
- 用于删除资源:请求没有
Body
- 不发送
Body
- 具有幂等性对应
1
2DELETE /users/1
Host: api.github.comRetrofifit
的代码:1
2
Call<User> getUser(; String id, String gender)
HEAD
- 和 GET 使用方法完全相同
- 和 GET 唯一区别在于,返回的响应中没有 Body
Status Code 状态码
三位数字,用于对响应结果做出类型化描述(如「获取成功」「内容未找到」)。
1xx
:临时性消息。如:100
(继续发送:一个请求拆分成多个请求,请求中带个except: 100
标识(其中except
可能不对))、101
(正在切换协议:问服务器是否支持(header
内有”Upgrade h2c
“)服务端不懂HTTP2
协议,返回101
切换成HTTP1
)2xx
:成功。最典型的是200
(OK)、201
(创建成功)。3xx
:重定向。如301
(永久移动)、302
(暂时移动)、304
(内容未改变)。4xx
:客户端错误。如400
(客户端请求错误)、401
(认证失败)、403
(被禁⽌)、404
(找不到内容)。5xx
:服务器错误。如500
(服务器内部错误)。
Header
⾸部
作用:HTTP
消息的元数据(metadata
)(数据的属性)。
元数据:数据的数据(从前有座山,山上有个老和尚对小和尚说“从前有座山,山上有个老和尚对小和尚说:‘…’”)
Host
⽬标主机。注意:不是在网络上用于寻址的,而是在目标服务器上用于定位子服务器的。(在请求刚开始就通过DNS
寻找对应的IP
地址)
Content-Type
指定 Body
的类型。主要有4
类:
text/html
- 请求
Web
页面时返回响应的类型,Body
中返回html
文本。格式如下:
1
2
3
4
5
6
7
8HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 853
<html>
<head>
<meta charset="utf-8">
......Content-Type: text/html;charset=utf-8
- 请求
x-www-form-urlencoded
- Web 页面纯文本表单的提交方式。
encoded URL
格式 Content-Type: application/x-www-form-urlencoded
1
2
3
4
5
6
7
8
9
10
11
12
13<form method="POST" enctype="application/x-www-form-urlencoded">
<div class="form-group">
<label>Name</label>
<input type="text" name="name" class="form-control" placeholder="姓名">
</div>
<div class="form-group">
<label>Name</label>
<input type="text" name="nickName" class="form-control" placeholder="昵称">
</div>
<p>
<button type="submit" class="btn btn-primary btn-lg">提交</button>
</p>
</form>格式如下:
1
2
3
4
5
6POST /users HTTP/1.1
HOST:api.github.com
Content-Type:application/x-www-form-urlencoded
Content-Length:27
name=renwuxian&gender=male对应
Retrofit
的代码1
2
3
Call<User> addUser(; String name, String gender)- Web 页面纯文本表单的提交方式。
multitype/form-data
- Web 页面含有二进制文件时的提交方式
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
1
2
3
4
5
6
7
8
9
10
11<form method="POST" enctype="multipart/form-data">
<div class="form-group">
<label>文件名</label>
<input type="text" class="form-control" name="name" placeholder="文件名">
</div>
<div class="form-group">
<label for="exampleInputFile">上传文件</label>
<input type="file" name="upload" id="exampleInputFile">
</div>
<button type="submit" class="btn btn-default">提交</button>
</form>格式如下:
1
2
3
4
5
6
7
8
9
10
11
12
13POST /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--对应
Retrofit
的代码:
1 |
|
application/json
,image/jpeg
,application/zip
…单项内容(文本或非文本都可以),用于
Web Api
的响应或者POST/PUT
的请求请求中提交
JSON
Content-Type: application/json; charset=utf-8
、Content-Type: image/jpeg
、Content-Type: application/zip
1 | POST /users HTTP/1.1 |
对应 Retrofifit
的代码:
1 |
|
响应中返回
JSON
1 | HTTP/1.1 200 OK |
请求中提交二进制内容
1 | POST /user/1/avatar HTTP/1.1 |
对应 Retrofifit
的代码:
1 |
|
相应中返回二进制内容
1 | HTTP/1.1 200 OK |
Content-Length
指定
Body
的长度(字节)。(如果没有长度,那么请求的内容是到哪里结束,服务器就不知道了)分块传输编码
Chunked Transfer Encoding
- 作用:用于当响应发起时,内容长度还没能确定的情况下(二进制传输内容无法确定,有可能混用了比如换行符等用来标识结束的符号)。和 Content-Length 不同时使用。用途是尽早给出响应,减少用户等待。
Transfer-Encoding: chunked
格式:
1 | HTTP/1.1 200 OK |
Location
指定重定向的⽬标 URL
User-Agent
- 用户代理【了解即可】
- 作用:即是谁实际发送请求、接受响应的,例如⼿机浏览器、某款⼿机 App。
Range / Accept-Range
按范围取数据
作用:断点续传、多线程下载。
Accept-Range: bytes
响应报文中出现,表示服务器⽀持按字节来取范围数据Range: bytes=<start>-<end>
请求报文中出现,表示要取哪段数据Content-Range:<start>-<end>/total
响应报文中出现,表示发送的是哪段数据
其他 Headers
Accept
: 客户端能接受的数据类型。如text/html
Accept-Charset
: 客户端接受的字符集。如utf-8
Accept-Encoding
: 客户端接受的压缩编码类型。如gzip
Content-Encoding
:压缩类型。如gzip
Cache
- 作用:在客户端或中间网络节点缓存数据,降低从服务器取数据的频率,以提⾼网络性能。
Cache-Control
:no-cache
、no-store
、max-age
Last-Modified
If-Modified-Since
Etag
If-None-Match
Cache-Control
:private/public
Cache和Buffer的 区别
Cache
:缓存,用过的等下还要用先存着Buffer
:缓冲,处理不过来先存着、等下生产来不及先存着,等下再使用
REST
REST
的定义众说纷纭,没有统一答案。
扔物线的观点:REST HTTP
即正确使用 HTTP
。包括:
使用资源的格式来定义
URL
规范地使用
method
来定义网络请求操作规范地使用
status code
来表示响应状态其他符合
HTTP
规范的设计准则