http报文结构
分为请求报文与响应报文
请求报文:
1>请求行
2>请求头
3>空行(把请求头与请求体隔开)
4>请求体
http请求方法
- post:提交数据
- get:请求数据
- put:修改数据
- delete:删除数据
- head:获取资源的元信息
- connect:建立连接隧道,用于代理服务器
- options:列出可对资源实行的请求方法,用来跨域请求
- trace:追踪请求-响应的传输路径
get与post
- 缓存角度:get 浏览器会默认缓存,留下缓存记录 post不会缓存
- 安全角度:get 参数放置在url post放在请求体中
- 编码方式:get 只能进行 URL 编码,只能接收 ASCII 字符 post没有限制
- TCP传输:get会一次性把请求报文发出去 post 会分为两个TCP数据包,会先发送请求头部分,如果服务器响应 100(continue), 然后发 body 部分。(火狐浏览器除外,它的 POST 请求只发一个 TCP 包)
http与tcp的区别
浏览器进程
2007年之前:单进程
- 不稳定(渲染引擎模块与插件的崩溃影响整个浏览器)
- 不流畅(内存泄露)
- 不安全(插件可以获取用户信息)
多进程:
- 浏览器主进程:界面显示,用户交互,子进程管理,存储功能等等
- 渲染进程:html,css,js的转化,v8,默认为每个tab标签创建一个渲染引擎
- 网络进程:网络资源加载
- GPU进程
- 插件进程:插件的运行
浏览器本地存储,优势与缺点
cookie,localStorage,sessionStorage,indexDB
cookie:
- 体积:最大为4k
- 性能:cookie紧跟域名,不管需不需要,都会携带完整cookie,造成性能浪费
- 安全:cookie以纯文本形式传递,容易被非法用户截获,在HttpOnly为 false 的情况下,Cookie 信息能直接通过 JS 脚本来读取。
localStorage:
- 体积:最大为5M
- 性能与安全:只存在于客户端,从而没有了性能与安全方面的问题
- 接口封装,调用方便
sessionStorage:
与localStorage一致,区别会话级别的存储,页面关闭,sessionStorage销毁
indexDB:
- 键值对存储。内部采用对象仓库存放数据,在这个对象仓库中数据采用键值对的方式来存储。
- 异步操作。数据库的读写属于 I/O 操作, 浏览器中对异步 I/O 提供了支持。
- 受同源策略限制,即无法访问跨域的数据库。
url到页面的呈现过程(以chorme为例)
- 构建请求
- 强缓存
- DNS解析(DNS数据缓存功能)
- 等待TCP队列(可能存在也可能不存在)
- 建立 TCP 连接
- 发送 HTTP 请求
- 网络响应
- 构建 DOM树
- 样式计算
- 生成布局树(Layout Tree)
- 布局树分层生成分层树
- 每个图层生成绘制列表,并将其提交到合成线程
- 光栅化
1.构建请求
当用户输入搜索内容或者url,根据相关url协议,来合成完整的url,当用户点击回车后,浏览器还有一个beforeunload事件,可以在该事件中当前页面执行一些数据清理或者提示用户确认离开的操作,也可以让浏览器不再进行后续工作,如果不监听该事件或者操作没有阻塞,开始加载下个页面,浏览器进程通过IPC机制,把url转发给网络进程
2.强缓存( 浏览器缓存)
- 强缓存不需要发起网络请求,首先检查的是强缓存
- 强缓存在http/1.0,使用的是Expires,过期时间
问题:服务器时间与浏览器时间不一致
http/1.1使用的是Cache-Control:过期时长
Cache-Control:max-age=3600
3.DNS解析
数据包是根据ip地址传递给对方的,所以需要根据域名得到ip地址,DNS是域名和IP地址相互映射的一个分布式数据库,所以DNS解析就是根据DNS得到具体ip地址的过程
如果之前某个域名已经解析过了,就不用进行解析了,提供了DNS 数据缓存服务
没有特别指明端口号,默认端口号为80
4.等待TCP队列
Chrome 有个机制,同一个域名同时最多只能建立 6 个 TCP 连接,如果在同一个域名下同时有 10 个请求发生,那么其中 4 个请求会进入排队等待状态,直至进行中的请求完成。
5.建立TCP连接
- 建立连接:三次握手
- 数据传输:接收端需要对每个数据包进行确认操作,在一段时间内没有确认,就判断为数据包丢失,进行重传机制;接收端会按照 TCP 头中的序号为其排序,从而保证组成完整的数据
- 断开连接:四次挥手
TCP保证了数据传输的可靠性,但也牺牲了数据包的传输速度
6.发送HTTP请求
浏览器发 HTTP 请求要携带三样东西:请求行、请求头和请求体
7.网络响应
- 缓存:请求头中携带相应的缓存tag向服务器发送请求,缓存tag分为: Last-Modified 和 ETag,Last-Modified 最后修改时间,在浏览器第一次给服务器发送请求后,服务器会在响应头中加上这个字段。浏览器接收到后,如果再次请求,会在请求头中携带If-Modified-Since字段,这个字段的值也就是服务器传来的最后修改时间。如果小于最后修改时间,就要更新,否则返回304走缓存 ETag 是服务器根据当前文件的内容,给文件生成的唯一标识,只要里面的内容有改动,这个值就会变。服务器通过响应头把这个值给浏览器。之后两者进行对比,不一样就要更新
在精准度上,ETag优于Last-Modified。优于 ETag 是按照内容给资源上标识,因此能准确感知资源的变化。而 Last-Modified 就不一样了,它在一些特殊的情况并不能准确感知资源变化,主要有两种情况:
编辑了资源文件,但是文件内容并没有更改,这样也会造成缓存失效。
Last-Modified 能够感知的单位时间是秒,如果文件在 1 秒内改变了多次,那么这时候的 Last-Modified 并没有体现出修改了。
在性能上,Last-Modified优于ETag,也很简单理解,Last-Modified仅仅只是记录一个时间点,而 Etag需要根据文件的具体内容生成哈希值。
另外,如果两种方式都支持的话,服务器会优先考虑ETag。
没有缓存的话,服务器进行处理,返回响应行、响应头和响应体,并将数据转发给浏览器进程,浏览器进程接收到网络进程的响应头数据之后,发送“提交导航 (CommitNavigation)”消息到渲染进程
所谓提交导航,就是指浏览器进程将网络进程接收到的 HTML 数据提交给渲染进程,具体流程是这样的:
- 首先当浏览器进程接收到网络进程的响应头数据之后,便向渲染进程发起“提交导航”的消息;
- 渲染进程接收到“提交导航”的消息后,会和网络进程建立传输数据的“管道”;
- 等文档数据传输完成之后,渲染进程会返回“确认提交”的消息给浏览器进程;
- 浏览器进程在收到“确认提交”的消息后,会更新浏览器界面状态,包括了安全状态、地址栏的 URL、前进后退的历史状态,并更新 Web 页面。