网络分层模型和应用协议
分层模型
分层模型的意义
当遇到一个复杂问题的时候,可以使用分层的思想把问题简单化。
比如, 你有一杯82年的可乐,想要分享给你的朋友张富贵,但你们已经很久没有联系,要完成这件事,你可能需要考虑:
- 我用什么装可乐
- 可能的方案:塑料瓶、玻璃瓶、煤气罐
- 怎么保证可乐始终保持低温?
- 可能的方案: 保温箱、小冰箱
- 如何保证可乐不被运输的人偷喝?
- 封条、在上面写毒药
- 如何获取张富贵的地址?
- 可能的方案: 报案失踪, 联系私人侦探、联系物流公司朋友
- 如何运输
- 可能的方案:自行车、汽车、火车、高铁、飞机、火箭
这样就形成了一个分层结构
从常理出发,我们可以得出以下结论:
- 每层相对独立,只解决自己的问题
- 每层无须考虑上层的交付,仅需把自己的结果交给下层即可
- 每层由多种方案可供选择,选择不同的方案不会对上下层造成影响
- 每一层会在上一层的基础上增加一些额外信息
五层网络模型
网络解决的问题是: 两个程序之间如果交换数据
这是一个非常复杂的问题,因为两个程序有可能出现在不同的设备上。
那么面对复杂的问题,可以使用分层的方式来简化
经过不断的演化,网络 最终形成了五层模型, 如下图所示
数据的传输
由一个程序(发送方)发送数据,数据在传输的过程中会进行五成网络模型从上到下的依次封装,在另一个程序(接收方)接收到数据之后,会将数据从下到上依次解封装,保证数据的正确性
四层、七层、五层网络模型
应用层协议
URL
URL(uniform resource locator, 统一资源定位符)用于定位网络服务
URL是一个固定格式的字符串
它表达了:
从网络中哪台计算机(domain)中的哪个程序(port)寻找哪个服务(path),并注明了获取服务的具体细节(query),以及要用什么样的协议通信(schema)
这里面包含了一些细节
- 当协议是http端口为80时,端口可以省略
- 当协议时https端口为443时,端口可以省略
- schema、domain、path是必填的,其他的根据具体要求填写
HTTP
超文本传输协议(Hyper Text Transfer Protocol,HTTP),是一个广泛运用于互联网的应用层协议
99%的情况下,前端开发者接触的都是HTTP协议
该协议规定了两个方面的内容:
- 传递消息的模式
- 传递消息的格式
传递消息的模式
HTTP使用了一种极为简单的消息传递模式,[请求 - 响应]模式
发起请求的称之为客户端,接收请求并完成响应的称之为服务器。【请求 - 响应】完成后,一次性交互结束
传递消息的格式
HTTP消息格式是一种纯文本的格式,文本分为三个部分:
请求行
请求头
// ⇐ 注意这里是有一个空行
请求体
具体每一部分写什么内容,要看具体的服务要求
发送请求的工具
有非常多的工具都可以发送http请求,比如 postman、apifox等,但这里推荐一个非常直观的工具
- vscode安装插件 REST Client
- 新建一个xxx.http 文件
- 编写请求脚本
POST /api/user/login HTTP/1.1
Host: study.duyiedu.com
Content-Type: application/json
{
"loginId":"admin",
"loginPwd":"123123"
}
- 发送请求
关键信息
请求方法
在请求行中的第一个单词是请求方法
在HTTP协议中,请求方法仅仅有语义的区别,只是表达了这次请求的【愿望】。
关于请求方法的协议原文见HTTP/1.1规范RFC7231-Chapte4
比如GET表达了客户端想要获取一些东西,POST表达了客户端想要提交一些东西,常见的请求方法有:
- GET:获取
- POST:提交
- PUT:修改
- DELETE:删除
具体在开发中应该选择什么请求方法,一定要看服务方的要求
通常情况下
- 获取数据一般使用GET
- 提交数据一般使用POST
- 各种静态资源的获取,一般使用GET
请求头 - HOST
HOST
标注了URL
地址中 的Domain + Port
示例:
Host: study.duyiedu.com
请求头 - Content-Type
Content-Type
标注了附带的请求具体是什么格式
比如,请求体的数据为loginId:admin, loginPwd:123456
, 请求体可以用不同的格式发出
Content-Type: application/x-www-form-urlencode
loginId=admin&loginPwd=123123
Content-Type: application/x-www-form-urlencode
{"loginId": "admin", "loginPwd": "123123"}
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryraPtlntBIqy4X2Ho
------WebKitFormBoundaryraPtlntBIqy4X2Ho
Content-Disposition: form-data; name="loginId"
admin
------WebKitFormBoundaryraPtlntBIqy4X2Ho
Content-Disposition: form-data; name="loginPwd"
123456
------WebKitFormBoundaryraPtlntBIqy4X2Ho--
响应码
响应码(状态码、消息码)是响应行中的一个数字,后面往往跟上一个对应的单词,用于表达服务器对这个响应的整体【态度】
常见的响应码大类有:
常见的状态码有
- 200 OK: 一切正常
- 301: 资源已被永久重定向
你的请求我收到了,但是呢,你要的东西不在这个地址了,我已经永远的把它移动到了一个新的地址,麻烦你取请求新的地址,地址我放到了响应头的Location中了
试试请求:www.douyutv.com - 302:资源已被临时重定向。
你的请求我收到了,但是呢,你要的东西不在这个地址了,我临时的把它移动到了一个新的地址,麻烦你取请求新的地址,地址我放到了请求头的Location中了
- 304:文档内容未被修改。
你的请求我收到了,你要的东西跟之前是一样的,没有任何的变化,所以我就不给你结果了,你自己就用以前的吧。啥?你没有缓存以前的内容,关我啥事
- 400:语义有误,当前请求无法被服务器理解
服务器无法识别为url地址内容
- 403: 服务器拒绝执行。
你的请求我已收到,但是我就是不给你东西
- 404: 资源不存在
你的请求我收到了,但我没有你要的东西
- 500: 服务器内部错误。
你的请求我已收到,但这道题我不会,解不出来,先睡了
响应头 - Content-Type
Content-Type
标注了附带的响应体是什么格式
常见的值有:
text/plain
: 普通纯文本text/html
:html文档text/javascript
或application/javascript
: js代码text/css
: css代码image/jpeg
: jpg图片attachment
:附件- 其他类型MIME文件