HTTP的概念、原理以及工作机制

HTTP 的定义

⼀种⽹络传输协议,位于 TCP / IP 协议族的最顶层——应⽤层

HTTP

Hypertext Transfer Protocol,超⽂本传输协议,和 HTML (Hypertext Markup Language 超⽂本标 记语⾔) ⼀起诞⽣,⽤于在⽹络上请求和传输 HTML 内容。
超⽂本,即「扩展型⽂本」,指的是 HTML 中可以有链向别的⽂本的链接(hyperlink)。

HTTP 的⼯作⽅式

浏览器:

⽤户输⼊地址后回⻋或点击链接 -> 浏览器拼装 HTTP 报⽂并发送请求给服务器 -> 服务器处理请求后发送响应报⽂给浏览器 -> 浏览器解析响应报⽂并使⽤渲染引擎显示到界⾯

⼿机 App:

⽤户点击或界⾯⾃动触发联⽹需求 -> Android 代码调⽤拼装 HTTP 报⽂并发送请求到服务器 -> 服务器处理请求后发送响应报⽂给⼿机 -> Android 代码处理响应报⽂并作出相应处理(如储存数据、加⼯数据、显示数据到界⾯)

URL 和 HTTP 报⽂

URL 格式

三部分:协议类型、服务器地址(和端⼝号)、路径(Path)

协议类型://服务器地址[:端⼝号]路径

http://hencoder.com/users?gender=male

报⽂格式

请求报⽂

响应报文

Request Method 请求⽅法

GET

     • ⽤于获取资源

     • 对服务器数据不进⾏修改

     • 不发送 Body

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

     • 用于增加或修改资源

     • 发送给服务器的内容写在Body里面

POST /users HTTP/1.1
Host: api.github.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 13
name=rengwuxian&gender=male

对应 Retrofit 的代码:

@FormUrlEncoded
@POST("/users")
Call<User> addUser(@Field("name") String name, @Field("gender") String
gender);

PUT

     • 用于修改资源

     • 发送给服务器的内容写在Body里面

PUT /users/1 HTTP/1.1
Host: api.github.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 13
gender=female

对应Retrofit的代码:

@FormUrlEncoded
@PUT("/users/{id}")
Call<User> updateGender(@Path("id") String id, @Field("gender") String
gender);

DELETE

     • 用于删除资源

     • 不发送 Body

DELETE /users/1 HTTP/1.1
Host: api.github.com
@DELETE("/users/{id}")
Call<User> getUser(@Path("id") String id, @Query("gender") String gender);

     • 对服务器数据不进⾏修改

     • 不发送 Body

HEAD

     • 和GET使用方法相同

     • 和GET唯一不同的是,返回响应中没有Body

Status Code 状态码

 三位数字,用于对响应结果做出类型化描述(如「获取成功」「内容未找到」)

     • 1xx:临时性消息。如:100(继续发送)、101(正在切换协议)

     • 2xx:成功。最典型的的是200(OK)、201(创建成功)

     • 3xx:重定向。如:301(永久移动)302(暂时移动)、304(内容未改变)

     • 4xx:客户端错误。如:400(客户端请求错误)、401(认证失败)、403(被禁止)、404(找不到内容)

     • 5xx:服务器错误。如:500(服务器内部错误)

Header首部

作用:HTTP消息的matadata

Host

目标主机。注意:不是在网络上用于寻址的,而是在目标服务器上用于定位子服务器的

Content-Type

指定Body的类型。主要有四类:

1.text/html

请求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"> 
......
2.x-www-form-urlencoded

Web页面纯文本表单的提交方式。



格式如下:

POST  /users  HTTP/1.1 
Host: api.github.com 
Content-Type: application/x-www-form-urlencoded 
Content-Length: 27

name=rengwuxian&gender=male

对应Retrofit的代码:

@FormUrlEncoded 
@POST("/users") 
Call<User> addUser(@Field("name") String name, @Field("gender") String gender);

3.multitype/form-data

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-

对应Retrofit的代码:

@Multipart 
@POST("/users") 
Call<User> addUser(@Part("name") RequestBody name, @Part("avatar") RequestBody avatar);

...

RequestBody namePart = RequestBody.create(MediaType.parse("text/plain"), nameStr); 
RequestBody avatarPart = RequestBody.create(MediaType.parse("image/jpeg"), avatarFile); 
api.addUser(namePart, avatarPart);

4.application/json,image/jpeg,application/zip...

单项内容(文本或非文本都可以),用于Web Api的响应或者POST/PUT的请求

| 请求中提交JSON

POST /users HTTP/1.1 
Host: hencoder.com 
Content-Type: application/json; charset=utf-8 
Content-Length: 38

{"name":"rengwuxian","gender":"male"}

对应Retrofit的代码:

@POST("/users") 
Call<User> addUser(@Body("user") User user);

...

// 需要使用JSON相关的Converter
api.addUser(user);

| 响应中返回的JSON

HTTP/1.1 200 OK 
content-type: application/json; charset=utf-8 
content-length: 234

[{"login":"mojombo","id":1,"node_id":"MDQ6VXNl cjE=","avatar_url":"https://avatars0.githubuse rcontent.com/u/1?v=4","gravat......

| 请求中提交的的二进制内容

POST /user/1/avatar HTTP/1.1 
Host: hencoder.com 
Content-Type: image/jpeg 
Content-Length: 1575

JFIFHH9......

对应的Retrofit代码:

@POST("users/{id}/avatar") 
Call<User> updateAvatar(@Path("id") String id, @Body RequestBody avatar);

...

RequestBody avatarBody = RequestBody.create(MediaType.parse("image/jpeg"), avatarFile); 
api.updateAvatar(id, avatarBody)

| 响应中返回的二进制内容

HTTP/1.1 200 OK 
content-type: image/jpeg 
content-length: 1575

JFIFHH9......

Content-Length

指定Body的长度(字节)

Transfer:chunked(分块传输编码Chunked Transfer Encoding)

用于当响应发起时,内容长度还没能确定的情况下。和Content-Length不能同时使用,用途是尽早给出响应,减少用户等待

格式:

HTTP/1.1 200 OK 
Content-Type: text/html 
Transfer-Encoding: chunked

4 
Chun 
9 
ked Trans 
12 
fer Encoding 
0

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(缓存) 和 Buffer(缓冲) 的区别

Cache 的作用是取用的东西可能一会还会用,那么我用完之后先不扔,先放着,下次用的时候直接拿来用。比如在网上取了一张图片,显示在我的软件中,很大可能这接下来的三天或者五天甚至半年,同样名字的图片不变还是这么个文件,那我就把它放在我的电脑或者手机的某个地方,下次打开软件时直接显示缓存在本地的图片,这是本地Cache。还有内存Cache,例如滑动列表某一条划出屏幕后,可能过一会用户有划回来了,我在从缓存中取出来显示,总之就是资源用过之后等一定时间很可能还会用,我暂时存起来,等内存不够的时候我在把它清掉,这就是Cache

Buffer 针对生产线,即上游生产的速度大于下游消费的速度,类似于RxJava中背压(Backpressure)机制


假如路人甲是开汉堡店的,有一天店里来了很多客人,他们都要吃汉堡,然后供不应求,第二天,店铺还没开门,路人甲先做一些汉堡,做好的汉堡先放面包柜保存,因为开门营业的时候可能还会有很多人来吃汉堡,就是路人甲(上游)提前生产,顾客(下游)还没有来买汉堡,但是顾客等会有可能来消费,这种提前生产然后放到一个地方,等待顾客消费这就是Buffer,还有一种是,刚开始的时候下游消费得快,上游也生产快,顾客买着买着,消费的慢了,这时路人甲没反应过来,还在不停地做汉堡,等路人甲察觉到时已经生产的多了,就放面包柜里面,这也叫缓冲。

猜你喜欢

转载自blog.csdn.net/l707941510/article/details/80910788