输入 url 后发生了什么
-
url 解析
- 检查是否为有效 url,无效则使用默认搜索引擎搜索内容
-
DNS 查询
- 查看是否有缓存
- 无缓存则依次查询 根域名服务器、顶级域名服务器、权威域名服务器,最后获取到 ip 地址
-
TCP 连接
- 三次握手建立连接
-
发送 http 请求
- https 使用 SSL 和 TLS 协议加密
- 发送初始的 http GET 请求
- http 请求报文:请求行(请求方法、url、协议版本);请求头(属性名:属性值)服务器据此获取客户端信息;请求体(键值对)
-
服务器响应请求
- http 响应报文:响应行(协议版本、状态码、状态描述);响应头(属性名:属性值);响应体(内容)
-
页面渲染
-
查看响应头信息,根据不同的指示做对应处理,比如重定向,存储 cookie,解压 gzip,缓存资源等等
-
解析 HTML,生成 DOM 树
- 遇到 script,defer:下载直到 HTML 解析完执行;async:在下载完后立即执行(多个 async,谁下载完就立即执行,完全独立)
-
解析 CSS,生成 CSS 树
-
合并 DOM 树和 CSS 树,生成渲染树
-
布局渲染树,负责元素尺寸、位置计算
-
绘制渲染树,绘制页面像素信息
-
将各层合并显示
-
浏览器存储
cookie
4kb
字段
-
Name
-
Value
-
Domain 域
-
Path 路径
-
Expires/Max-age
-
Size
-
HttpOnly 仅在 http 层面传输,客户端无法操作 cookie,防止 XSS
-
secure 是否在 https 上传输
...
多个 cookie 以 ; 隔开
localstorage
5m
只能存字符串,存储对象 [Object object]
持久化存储
sessionstorage
同 localstorage
会话期间存在
浏览器缓存
强缓存
expires
http1.0 规范,GMT 格式字符串:Expires:Mon,18 Oct 2066 23:59:59 GMT
cache-control
no-store // 不走缓存
no-cache // 协商缓存
max-age // 设置强缓存时间 Cache-Control:max-age=3600 3600ms
协商缓存
Last-Modified/If-Modified-Since
GMT 格式字符串
Etag/If-None-Match
为什么要有 Etag?
-
一些文件也许会周期性的更改,但是内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新 GET
-
某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说 1s 内修改了 N 次),
If-Modified-Since能检查到的粒度是秒级的,使用Etag就能够保证这种需求下客户端在 1 秒内能刷新 N 次 cache -
某些服务器不能精确的得到文件的最后修改时间
优先级
Cache-Control > expires > Etag > Last-Modified
刷新对缓存的影响
-
正常操作:地址栏输入 url,跳转链接,前进后退等
-
手动刷新:f5,点击刷新按钮,右键菜单刷新
-
强制刷新:ctrl + f5,shift+command+r
正常操作:强制缓存有效,协商缓存有效。 手动刷新:强制缓存失效,协商缓存有效。 强制刷新:强制缓存失效,协商缓存失效
http版本
1.0
-
短连接,每次请求都需要建立 TCP 连接 Connection: close
-
不支持断点续传
-
认为每台服务器绑定唯一的 ip
1.1
-
默认支持长连接 Connection: keep-alive
-
满足不用等待上一次请求结果,可以继续发送请求,但服务器必须按顺序返回请求结果
-
新增更多缓存控制策略 If-modified-Since, Last-modified, If-None-Match, E-tag 等
-
支持只发送 header 信息
-
支持 host 域
2.0
-
多路复用,同一个连接并发处理多个请求
-
二进制分帧,采用二进制传输数据,1.x 使用的是文本格式
-
头部数据压缩,使用 HPACK 对 header 数据进行压缩
-
服务器推送
Get/Post区别
-
从缓存的角度,GET 请求会被浏览器主动缓存下来,留下历史记录,而 POST 默认不会
-
从编码的角度,GET 只能进行 URL 编码,只能接收 ASCII 字符,而 POST 没有限制
-
从参数的角度,GET 一般放在 URL 中,因此不安全,POST 放在请求体中,更适合传输敏感信息
-
从幂等性的角度,GET 是幂等的,而 POST 不是。(幂等表示执行相同的操作,结果也是相同的)
-
从 TCP 的角度,GET 请求会把请求报文一次性发出去,而 POST 会分为两个 TCP 数据包,首先发 header 部分,如果服务器响应 100(continue), 然后发 body 部分。(火狐浏览器除外,它的 POST 请求只发一个 TCP 包)