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的请求请求中提交
JSONContent-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/htmlAccept-Charset: 客户端接受的字符集。如utf-8Accept-Encoding: 客户端接受的压缩编码类型。如gzipContent-Encoding:压缩类型。如gzip
Cache
- 作用:在客户端或中间网络节点缓存数据,降低从服务器取数据的频率,以提⾼网络性能。
Cache-Control:no-cache、no-store、max-ageLast-ModifiedIf-Modified-Since
EtagIf-None-Match
Cache-Control:private/public
Cache和Buffer的 区别
Cache:缓存,用过的等下还要用先存着Buffer:缓冲,处理不过来先存着、等下生产来不及先存着,等下再使用
REST
REST 的定义众说纷纭,没有统一答案。
扔物线的观点:REST HTTP 即正确使用 HTTP。包括:
使用资源的格式来定义
URL规范地使用
method来定义网络请求操作规范地使用
status code来表示响应状态其他符合
HTTP规范的设计准则