本文参考链接:
fecommunity.github.io/front-end-i… www.dailichun.com/2018/03/12/… zhuanlan.zhihu.com/p/80551769
小林coding的图解网络
〇、 在浏览器地址栏输入 url
一、浏览器检查缓存
浏览器查看是否有请求资源的强缓存:
- 如果请求资源在缓存中,且没有过期,跳转到解析步骤。
- 如果资源未缓存,发起新请求
1 HTTP 缓存技术
HTTP 缓存技术是一项提升HTTP性能的方法,对于一些重复性的HTTP请求,每次获得的数据都是一样的,将这些数据缓存到本地,就可以直接读取本地的数据,不必通过网络获取服务器响应。
HTTP 缓存有两种实现方式,分别是强制缓存和协商缓存。
1.1 强制缓存
强制缓存: 强缓存指的是只要浏览器判断缓存没有过期,则直接使用浏览器的本地缓存。浏览器决定是否使用缓存。
强制缓存的头部字段:
- Cache-Control: 相对时间(优先级更高)
- Expires: 绝对时间
强制缓存的实现过程:
- 当浏览器第一次请求访问服务器资源时,服务器会在返回这个资源的同时,在 Response 头部加上 Cache-Control,Cache-Control 中设置了过期时间大小;
- 浏览器再次请求访问服务器中的该资源时,会先通过请求资源的时间与 Cache-Control 中设置的过期时间大小,来计算出该资源是否过期,如果没有,则使用该缓存,否则重新请求服务器;
- 服务器再次收到请求后,会再次更新 Response 头部的 Cache-Control
1.2 协商缓存
协商缓存: 配合强缓存中Cache-Control使用,在未能命中强缓存时,且存在协商缓存头部,那么客户端将于服务端进行协商,通过协商结果判断是否使用本地缓存。
头部字段:
- 请求头部中的
If-Modified-Since响应头部中的Last-Modified
- 响应头部中的
Last-Modified:标示这个响应资源的最后修改时间 - 请求头部中的
If-Modified-Since:当资源过期了,发现响应头中具有 Last-Modified 声明,则再次发起请求的时候,携带If-Modified-Since字段,其值为上次响应头部中Last-Modified的值。服务器收到后将If-Modified-Since的值和被请求资源的最后修改时间进行对比,如果最后修改时间较新(大),说明资源又被改过,则返回最新资源,HTTP 200 OK;如果最后修改时间较旧(小),说明资源无新修改,响应 HTTP 304 走缓存。
- 请求头部中的
If-None-Match响应头部中的ETag
- 响应头部中
Etag:唯一标识响应资源; - 请求头部中的
If-None-Match:当资源过期时,浏览器发现响应头里有 Etag,则再次向服务器发起请求时,会将请求头If-None-Match 值设置为 Etag 的值。服务器收到请求后进行比对,如果资源没有变化返回 304,如果资源变化了返回 200。
Etag的优先级更高: 服务端先会判断 Etag 是否变化了,如果 Etag 有变化就不用在判断 Last-Modified 了,如果 Etag 没有变化,然后再看 Last-Modified。
原因:
- 在没有修改文件内容情况下文件的最后修改时间可能也会改变,这会导致客户端认为这文件被改动了,从而重新请求;
- 可能有些文件是在秒级以内修改的,
If-Modified-Since能检查到的粒度是秒级的,使用 Etag就能够保证这种需求下客户端在 1 秒内能刷新多次; - 有些服务器不能精确获取文件的最后修改时间。
协商缓存和强制缓存的工作流程:
二、浏览器解析URL
什么是 URL
URL 是英文 Uniform Resource Locator 的简称,中文译为统一资源定位符。
统一资源定位符的标准格式如下:
[协议类型]://[服务器地址]:[端口号]/[资源层级UNIX文件路径][文件名]?[查询]#[片段ID]
统一资源定位符的完整格式如下:
[协议类型]://[访问资源需要的凭证信息]@[服务器地址]:[端口号]/[资源层级UNIX文件路径][文件名]?[查询]#[片段ID]
其中访问凭证信息、端口号、查询、片段ID都属于选填项。
举例:
http://www.example.com:80/path/to/myfile.htmlkey1=value1&key2=value2#SomewhereInTheDocument
http 是协议(protocol),表明浏览器使用何种协议。
www.example.com是域名(Domain Name), 表明正在请求用哪个web服务器。
:80 端口,HTTP 为80, HTTPS 为443,一般可以忽略。
/path/to/myfile.html/ 路径
?key1=value1&key2=value2 参数(parameters),可以执行部分操作。
#SomewhereInTheDocument 锚点(anchor),将到达锚点定义的位置。注意,锚点后面的内容不会发送请求到服务器。
解析 URL
- 正则表达式解析(太麻烦,暂时先不写)
- URL构造函数解析
URL() 构造函数返回一个新创建的 URL 对象,表示由一组参数定义的 URL。如果给定的基本 URL 或生成的 URL 不是有效的 URL 链接,则会抛出一个 TypeError。
语法:new URL(url [, base]);
示例
// 直接使用绝对 URL 地址方式调用
const url = new URL('http://example.com/path/index.html');
// 使用 path 加 base 地址参数的方式调用
const url = new URL('/path/index.html', 'http://example.com');
对URL进行解析之后,浏览器确定了 Web 服务器和文件名,接下来就是根据这些信息来生成 HTTP 请求消息了。(组装HTTP请求报文)
三、DNS 解析
DNS域名解析:将域名网址自动转换为具体的 IP 地址。
域名的层级关系
DNS 中的域名都是用句点来分隔的,比如 www.server.com,这里的句点代表了不同层次之间的界限。
在域名中,越靠右的位置表示其层级越高。
根域是在最顶层,它的下一层就是 com 顶级域,再下面是 server.com。
所以域名的层级关系类似一个树状结构:
- 根 DNS 服务器
- 顶级域 DNS 服务器(com)
- 权威 DNS 服务器(server.com)
域名解析的工作流程
- 浏览器检查自己的缓存-> 查找操作系统的缓存 -> 检查本机域名文件hosts -> DNS查询
- 客户端首先会发出一个 DNS 请求,问 www.server.com 的 IP 是啥,并发给本地 DNS 服务器
- 本地域名服务器收到客户端的请求后,如果缓存里的表格能找到 www.server.com,则它直接返回 IP 地址。如果没有,本地 DNS 会去问它的根域名服务器:“老大, 能告诉我 www.server.com 的 IP 地址吗?” 根域名服务器是最高层次的,它不直接用于域名解析,但能指明一条道路。
- 根 DNS 收到来自本地 DNS 的请求后,发现后置是 .com,说:“www.server.com 这个域名归 .com 区域管理,我给你 .com 顶级域名服务器地址给你,你去问问它吧。”
- 本地 DNS 收到顶级域名服务器的地址后,发起请求问“老二, 你能告诉我 www.server.com 的 IP 地址吗?”
- 顶级域名服务器说:“我给你负责 www.server.com 区域的权威 DNS 服务器的地址,你去问它应该能问到”。
- 本地 DNS 于是转向问权威 DNS 服务器:“老三,www.server.com对应的IP是啥呀?” server.com 的权威 DNS 服务器,它是域名解析结果的原出处。为啥叫权威呢?就是我的域名我做主。
- 权威 DNS 服务器查询后将对应的 IP 地址 X.X.X.X 告诉本地 DNS。
- 本地 DNS 再将 IP 地址返回客户端,客户端和目标建立连接。