日常的开发中,大家关注的重点基本都在前端的展现、交互和性能上,而这些都算是浏览器上层的一些表现。而对于底层的一些协议关注的相对较少,这里就主要介绍一下这些基础协议。
基础协议有很多,这里主要介绍一下最常见的http、https、tcp/udp协议。
基本概念
协议是多方之间相互商定的一种沟通或统一行动时的一种规则。互联网协议也是一样,规定了不同终端之间通信时数据传输的方式、格式等内容。在七层网络模型中存在着各种不同的协议,其中
http (Hypertext Transfer Protocol)超文本传输协议,是一种处于应用层的,服务器与浏览器之间进行文本传输的无状态协议。
https (Hypertext Transfer Protocol over Secure Socket Layer)基于SSL的HTTP协议,可以理解为加密型的http协议,同时https一般都不在使用http的默认80端口,改用433端口。
TCP (Transmission Control Protocol)传输控制协议,一种面向连接的、可靠的、基于字节流的传输层通信协议。
UDP (User Datagram Protocol)用户数据协议,与TCP类似,也是一种传输层协议,不同的是,它是一种面向无连接的、不可靠的协议。
一次HTTP请求的过程中都发生了什么?
这是一道经典的前端面试题,刚毕业找工作的过程中被问了N遍。简而言之,从你输入网址到你看到页面,大致经历了以下过程
1、域名解析—–有求于人,总要先找到人家吧。
2、建立连接—–找到地址了,快快联络,相互认识总是要的。
3、发送请求—–提出请求,等待回复。
4、接收响应—–得到回复,准备开工。
5、渲染页面—–开工盖房,盖完收工。
下面先从网址说起
网址?URL?
我们现在所说的网址,也称之为URL,全称Uniform Resource Locator。用于表明某一资源在网络上的地址。基本格式如下
schema://host[:port#]/path/…/[?search][#hash]
scheme 指定低层使用的协议(例如:http, https, ftp)
host HTTP服务器的IP地址或者域名
port# HTTP服务器的默认端口是80,这种情况下端口号可以省略。
path 访问资源的路径
search 发送给http服务器的数据
hash 哈希
其中hash是不会传给服务器的,并且hash后面的部分在url解析的时候也会被当作hash,因此hash必须放在最后,避免其他信息被影响。
域名解析,找到真正的门牌号
通常情况下我们在浏览器窗口输入的网址都不是目标的原始地址,而是一种为了方便记忆的语义化之后的地址。而在网络中一个终端的实际地址其实是IP地址。为了实现与服务器的通信,首要的就是找到服务器的IP地址,而由网址到IP地址的解析过程即为域名解析。
域名解析大致分为几个步骤
1、浏览器缓存解析,在chrome中可以使用chrome://net-internals/#dns命令查询浏览器缓存。
2、本机缓存解析 ,windows下可以在dos窗口使用ipconfig /displaydns命令查询本机缓存。
3、本机host,BIOS缓存解析
4、向DNS服务器发送请求解析,这种解析请求是面向无连接的,客户端只是发送请求,没收到回复就继续请求。本身不存在一个确认双方连接状态的过程,属于一种不安全、稳定的通信,而这就是UDP协议的一个表现。
每一步中如果解析出结果就停止向下解析,返回IP地址。这也就是我们在平时的工作中会去配置host文件,以达到对不同环境映射的原理。
三次握手?在么?在?有个请求
在完成了域名解析之后,浏览器确定了服务器地址。那么就要开始通信了。为了确保准确的连接到服务器,确保通信成功,这个时候通过传输层tcp协议开始三次握手。
1)浏览器手心发送一个连接请求,同时进入请求已发送状态,等待服务器的回复 2)服务器接收到请求后,则向浏览器返回一个确认信息,并进入请求已接收状态,等待浏览器再次确认。
3)浏览器端再次发送一个连接确认信号,并进入连接准备状态,服务端确认后也进入准备状态,双方即可开始通信。
与http不同的是,https会在三次握手的过程中将加密协议等信息一并传输,最终在建立连接之后浏览器与服务器之间的通信数据,就可以通过加密来保证通信的安全性。
请求响应数据?给我这个,好 拿去
建立连接后,双方开始http协议通信。而在这个通信过程中,双方都对数据添加了一些额外的信息来表明双方需要的什么样的格式、那种缓存策略、安全机制等等,这些信息就是头部信息/首部信息。
首部信息大致可以分成三个部分,
1)通用部分
2)请求头部分
3)响应头部分
通用部分
请求与响应都遵守的通用部分主要包括一些基本的连接信息和缓存信息等等,如
首部 | 描述 |
---|---|
Connection | 允许客户端和服务器指定与请求/响应连接有关的选项,http1.1版本默认keep-alive |
Date | 提供日期和时间标志,说明报文是什么时间创建的 |
MIME-Version | 给出了发送端使用的MIME版本 |
Via | 显示了报文经过的中间节点(代理、网关) |
Cache-Control | 用于随报文传送缓存指示,no-cache不缓存 |
Pragma | 另一种随报文传送指示的方式,但并不专用于缓存,no-cache不缓存 |
请求头信息
请求头信息主要用于向服务器说明是从哪里发出的请求、请求什么格式的数据、请求数据时有什么偏好、中间经过的一些代理以及浏览器自身的一些属性等等。
首部 | 描述 |
---|---|
基础信息 | 基础信息 |
Host | 给出了接收请求的服务器的主机名和端口号 |
Referer | 提供了包含当前请求URI的文档的URL |
User-Agent | 将发起请求的应用程序名称告知服务器(User-Agent)用户代理 |
Accept | 告诉服务器能够发送哪些媒体类型,此外还有Accept-Charset、Accept-Encoding、Accept-Language |
条件信息 | 条件信息 |
Expect | 允许客户端列出某请求所要求的服务器行为 |
If-Match | 如果实体标记与文档当前的实体标记相匹配,就或者这份文档 |
If-Modified-Since | 除非在某个指定的日期之后资源被修改过,否则就限制这个请求 |
If-Range | 允许对文档的某个范围进行条件请求 |
If-Unmodified-Since | 除非在某个指定的日期之后资源没有被修改过,否则就限制这个请求 |
Range | 如果服务器支持范围请求,就请求资源的指定范围 |
安全认证信息 | 安全认证信息 |
Authorization | 包含了客户端提供给服务器,以便对其自身进行认证的数据 |
Cookie | 客户端用它想服务器传送一个令牌-他并不是真正的安全首部,但却是隐含了安全功能 |
代理信息 | 代理信息 |
Proxy-Authorization | 与Authorization首部相同,但这个首部是在与代理进行认证时使用的 |
Proxy-Connection | 与Connection首部相同,但这个首部是在于代理建立连接时使用的 |
响应头信息
响应头则主要是向浏览器说明服务器是从哪里响应、响应的内容有多大、遵循什么规范以及一些代理、安全认证信息等等,以便于浏览器更好地更快更安全的处理数据。
首部 | 描述 |
---|---|
基础信息 | 基础信息 |
Age | (从最初创建开始)响应持续时间 |
Public | 服务器为其资源支持的请求方法列表 |
Server | 服务器应用程序软件的名称和版本 |
Accept-Ranges | 对此资源来说,服务器可接受的范围类型 |
Vary | 服务器查看的其他首部的列表,可能会使响应发生变化;也就是说,这是一个首部列表,服务器会根据这些首部的内容挑选出最合适的资源版本发送给客户端。 |
安全认证信息 | 安全认证信息 |
Proxy-Authenticate | 来自代理的对客户端的质询列表 |
Set-Cookie | 不是真正的安全首部,但隐含有安全功能;可以在客户端设置一个令牌,以便服务器对客户端进行标识。此外还有Set-Cookie2 |
缓存信息 | 缓存信息 |
ETag | 与此实体有关的实体标记 |
Expires | 实体不在有效,要从原始的源端再次获取此实体的日期和时间 |
Last-Modified | 这个实体最后一次被修改的日期和时间 |
响应实体信息 | 响应实体信息 |
Content-Type | 这个主体的对象模型 |
Content-MD5 | 主体的MD5校验,此外还有Content-Base,Content-Encoding,Content-Language,Content-Length,Content-Location,Content-Range |
除此之外http协议中还定义了一些额外的头部信息辅助通信,比如用于处理跨域请求的
首部 | 描述 |
---|---|
跨域信息 | 跨域信息 |
Access-Control-Allow-Origin | 允许的访问域,一般设为* |
Access-Control-Allow-Methods | 允许的请求方式列表,如POST, GET, OPTIONS,DELETE,PUT |
数据加载、渲染
这个在这部分不做细讲。
说到这里,一次http请求的大致过程就说完了,其中也包括了http、tcp/udp协议的一些信息,并不详细,主要供给大家做一个简略的介绍。下面在简要介绍一些我们工作中经常用到的东西。
代理
代理在我们的工作用应用很多,比如FQ用的VPN代理,映射文件的nginx,CDN服务器、代理软件Charles、fidder等等,严格的说host本身也算得上是一种代理。而代理又分为正向代理和反向代理。
正向代理介于客户端与服务器之间,此时客户端一般不能直接访问服务器,而代理服务器可以。这种情况下,中间代理就成为了一个请求与响应的中转站,转发我们的请求,并把服务器的响应转回给我们。也就是我们平常使用vpnFQ时的状态。
而反向代理呢,一般作用在服务端,把用户的请求映射到不同的实际资源地址上去。就像我们在平时使用nginx一样,把一系列的请求映射到本地。这一点和Charles这些代理软件,原理上都是一样的。
再比如CDN,内容分发网络,本身也是一种反向代理。CDN首先会在DNS解析阶段拿到优先解析的特权,并把DNS解析的请求发送给CDN服务器。服务器会根据用户的IP,就近的选择一台缓存服务器,并告知用户去和这个服务器通信。这样,用户在访问时就可以把请求定向到距离用户最近的网络节点上,降低请求节点距离,提高请求效率。这也就是CDN要相对比较快的原因啦。