目录
- 网络分层模型
- OSI七层模型
- TCP/IP四层模型
- TCP/IP五层模型
- HTTP
- 传递消息的模式
- 传递消息的格式
- 响应码
- URL
- 用户代理/user agent
- 自动发送请求
- 自动解析响应
- AJAX
- XHR
- Fetch
- 跨域
- 同源与异源
- 网络通信中的跨域
- 浏览器对跨域的限制
- CORS
- 简单请求
- 对简单请求的验证
- 预检请求
- 对预检请求的验证
- JOSNP
- 代理
- GET与POST
- 结尾
- 本博客依据独一教育前端web大师课撰写
网络分层模型
分层
是为了将复杂问题简单化,网络要解决的复杂问题是:两个程序之间的数据交换
分层
之后,每一层都只用解决自己的问题,每层也相对独立
每层都有不同的解决方案
选择,使用不同的方案也会对上下层抉择产生一定的影响
每一层在传递数据时都会往数据
中增加一些额外信息
OSI七层模型
由ISO
组织提出的互联网模型,一共有七层
,从下到上分别为物理层,数据链路层,网络层,传输层,会话层,表示层,应用层
OSI模型
的出现极大地推进了网络标准化
的进程,但因其分层太过复杂所以在实际应用中并不常见
TCP/IP四层模型
除了标准的OSI七层模型
外还有TCP/IP四层模型
从下到上分别为物理层,网络层,传输层,应用层
相较于OSI七层模型
,它将物理层和数据链路层合并为物理层,将应用层,表示层,会话层合并为应用层
,简化了模型的复杂度
TCP/IP五层模型
综合了OSI模型
和TCP/IP四层模型
的优点,将应用层,表示层,会话层进行合并,并且对物理层进行拆分
从下到上分别为:物理层,数据链路层,网络层,传输层,应用层
HTTP
超文本传输协议
,是整个互联网通信的基础
该协议规定了两个方面的内容
传递消息的模式
通过请求-响应
的模式
发起请求
的一端被称为客户端
接受请求
的一端被称为服务端
请求-响应
完成后意味着这一次交互
结束
传递消息的格式
HTTP
的消息格式为纯文本
格式,文本包含三个部分,这里主要了解请求
-
行/Line
在请求行中主要包含三个部分- 请求方法
如get
,post
,put
,delete
等等
在HTTP
协议中,请求方法仅有语义
的区别,如GET
表达了客户端想要获取一些东西,POST
表达了客户端想要提交一些东西 - 地址
表明在此URL
上你想要访问那些资源 - 协议版本
为使用的http
协议版本
以下为一个最基本的请求行
- 请求方法
GET / HTTP/1.1
-
头/Header
采用键值对
的形式
常见的字段Host
对方的主机域名Content-Type
用于规定请求体里的格式
注意:这里的值需要查看接口文档,必须是服务端能接受的格式Cookie
用于发送cookie信息User-Agent
标识客户端代理名称和版本号
以下一个简单的请求头
Host: www.baidu.com
Content-Type: application/josn
- 体/Body
存放需要发送往服务端的数据
,数据的格式
由请求头的Content-Type
决定
注意,无论是否需要请求体,在请求头后面都需要换行两次
注意:application/json
字符串被称为MIME标准格式的字符串
常见MIME
字符串如下
application/josn
代表了会传送json数据application/javascript
代表了会传送JavaScript数据text/html
代表了会传送一个html数据text/css
代表了会传送一个css数据text/plain
代表了会传送一个文本数据img/png
代表了会传送一个图片数据
VSCode
中有一个插件可以不用通过浏览器就能发送http
请求
响应码
客户端向服务端发送请求后会得到服务端的响应
,其中响应码
代表了这次交互的状态
200
:一切正常301
:资源被永久重定向
新的地址将会放在响应头的Location中302
:资源被临时重定向
新的地址通样会被放入到响应头的Location中304
:文档内容未修改
内容未改变,不会返回资源,需要客户端从缓存中提取400
:语法错误
通常会返回一个错误信息,告知客户端出现了什么问题403
:服务端拒绝执行
通常是无访问权限404
:资源不存在500
:服务器内部错误
URL
被称为统一资源定位符
,是互联网上用于指定资源的地址,URL由多部分组成
他表明了从网络中哪台计算机(domain)
中的哪个程序(port)
寻找哪个资源(path)
,并注明了获取资源的具体细节(query)
,以及要用什么样的协议通信(schema)
-
协议/schema
即访问这个资源所需要的协议,如http
,ftp
等等 -
主机名/domain
即域名或者ip地址,如www.baidu.com
,192.168.1.1
等等 -
端口/port
即访问这个资源需要连接哪个端口
,不同服务都会开设不同端口
端口号是无意义
的,访问资源时需要查看接口文档
http协议默认端口号是80
,https默认端口号是443
-
路径/path
即资源在服务端的具体路径
注意,这里的路径和服务端文件具体存放路径并不对应,路径中访问的index.html之类的文件在服务端有时也并不存在,具体什么路径能拿到哪些资源需要查看接口文档
-
查询参数/query
即访问这个资源时需要传递的参数
使用?开头;分隔
,以属性名=属性值
的形式传递在URL上 -
锚点/hash
即页面内部的锚点,用于页面内部的快速跳转
使用#开头
用户代理/user agent
浏览器可以代替用户完成http
请求,代替用户解析响应结果
自动发送请求
当用户进行了一些操作后,浏览器会自动发送http
请求
- 当用户点击了a元素后
浏览器拿到a元素的href
地址,并发出一个GET
请求,同时抛弃
此页面 - 当用户点击了表单中的button元素时
浏览器获取button元素存在的form表单获取它的action
属性,并依据method
属性中规定的请求方法携带着form表单中的数据
发出请求 - 当浏览器解析遇到了link,img,script,video等元素时
会向他们定好的地址发送GET请求
- 当用户在地址栏键入了URL地址时
会向当前地址发送GET
请求并抛弃
此页面 - 当用户点击刷新时
浏览器会向当前地址重新发送一遍与上一次一样的请求
,并同时抛弃
此页面
自动解析响应
在得到响应结果时,浏览器也会自动进行解析
- 处理
响应码
浏览器会自动识别响应码并自动完成对应的处理 - 解析
响应数据
浏览器能自动根据Content-Type
里规定的值来对响应体
进行解析运行
例如application/javascript
浏览器就会使用js引擎
执行
text/plain
浏览器就会原封不动的放入页面中
具体可查看我上文写的MIME
字符串部分
AJAX
AJAX
指在浏览器中异步向服务端发送请求
他有两种实现方式
XHR
具体可看我这篇关于XHR
的文章
(未动笔,未来可寄)
Fetch
具体可看我这片关于Fetch
的文章
(未动笔,未来可寄)
跨域
当一个源
向另一个源
发出通信请求
时,同源策略
就会对这个通信做出不同程度的限制
由此限制
产生的问题就叫做跨域
同源与异源
同源
是指协议、域名、端口全部相同
的两个 URL
,它们之间的交互没有限制;而不同源的 URL 之间的交互会受到同源策略
的限制。
两个URL地址的源
完全相同就叫做同源
,只要有一样不同就叫做异源
异源
就会造成跨域
问题
网络通信中的跨域
当浏览器运行页面后,会发出很多的网络请求,例如CSS
、JS
、图片
、AJAX
等等
请求页面的源称之为页面源
,在该页面中发出的请求称之为目标源
当页面源和目标源一致
时,则为同源请求
,否则为异源请求
(跨域请求
)
浏览器对跨域的限制
浏览器对跨域
问题的限制可以总结为两点:
- 对
标签页
发出的跨域请求轻微限制
- 对
AJAX
发出的跨域请求严厉限制
注意:浏览器在对跨域校验
时并不是在发送请求
这一步,而是在服务端得到请求发送响应
给浏览器时进行跨域的校验
,如果校验不通过就会引发跨域
问题,通过了就交付
这个响应
CORS
第一种解决方案就是CORS
,同时也是浏览器推荐的解决方案
CORS作用于浏览器校验部分,是一套校验规则
基本理念是只要服务端明确表示允许的才能通过
CORS
将请求分为两类
简单请求
只要满足以下条件的就是简单请求
请求方法
为GET
,POST
,HEAD
之一头部字段满足CORS安全规范
具体参见: W3C- 如果
Content-Type
则值必须是其中一个
text/plain
multipart/form-data
application/x-www-form-urlencoded
对简单请求的验证
浏览器会发送一个真实请求
给服务端
,同时会在请求中加入一个字段Origin
用于代表源
服务端也会返回一个响应
,响应中包含一个字段Access-Control-Allow-Origin
用于标识允许通过的源
//真实请求添加的字段
Origin: http://a.com
//响应添加的字段
Access-Control-Allow-Origin: http://a.com
预检请求
一切不符合简单请求的请求都是预检请求
对预检请求的验证
不同于简单请求直接发送一个真实的请求,预检请求需要先发送一个OPTIONS请求
OPTIONS请求中包含了请求的源,请求方法,以及请求头中更改的字段有哪些
浏览器在接受到了OPTIONS请求后就会发送一个响应
响应中包含了同意经过的源,同意经过的方法,同意经过的被更改过的字段,以及一个可选参数最长时间
只有在通过
之后客户端才能向服务端发送真实请求
//OPTIONS请求
Origin: http://a.com
Access-Control-Request-Method: ABC
Access-Control-Request-Headers: a, b, content-type
//响应
Access-Control-Allow-Origin: http://a.com
Access-Control-Request-Method: ABC
Access-Control-Request-Headers: a, b, content-type
Access-Control-Request-Max-Age: 86400 //这个参数为询问一次后多长时间内不需要再次发送OPTIONS请求,单位为秒
JOSNP
在CORS
出来以前,人们解决跨域问题的方案通常是JOSNP
JOSNP
通常会创建一个script
元素来向目标地址
发送请求
,因为是通过标签来发送所以跨域的限制会比较轻微
服务端
的响应结果是一个函数调用
,并将响应数据给参数
注意:JOSNP仅能发送GET请求
容易被恶意网站调用
恶意攻击者可能会利用callback=恶意函数的形式进行XSS攻击
更多关于JOSNP
的内容可以看我下面这篇博客
(未动笔,未来可寄)
代理
用户端可以通过一个代理服务器
发起请求,由代理服务器
向真正的目标地址
发起请求,再将得到的响应返回
给用户端
GET与POST
事实上,浏览器都有一个约定
,就是GET请求是默认不带请求体
的,这也就意味着我们无法使用GET请求来传输大量数据
可以使用URL
的形式来传递数据,但每个浏览器都会对URL的长度进行限制
,具体浏览器的具体版本,限制的长度都不同,并且因为数据都在URL中,可以很轻松的复现页面,这也导致暴露了隐私数据
GET
请求只能传递ASCII
码数据,非ASCII
码数据需要进行编码
POST
请求不会保存到浏览记录中
POST
请求的页面如果进行刷新
的话,浏览器会提示用户是否重新提交