前端浏览器网络系列进阶(本地储存,缓存,网络,协议,安全)
前言
前端眼里只有 Js, Vue,React, Node 嘛 ?
不 !
答案很明显,现在的前端真的很强大,很复杂 ......
- 要会 html , css ,Js
- 紧跟着用框架呀 Jquery , bootstarp ,angularJs.1x.2x
- 很不巧 Vue 和 React 成为了主流
- 小程序悄然而生
- 跨平台能行嘛 ? React Native , flutter
- 放弃服务器端吧 Node 蹦出来了
- ......
再加上各种 UI
框架,构建工具,前端的方向也算是四面八方, 我的天呐,痛苦 !
可是有一个知识点,在前端领域里边是必要的,浏览器
,关于浏览器知识,在如今的前端中也显的尤为重要了,面试中频繁被问及到,各种本地储存,缓存,网络,Http, Tcp/IP, 安全 等等,今天就跟我一起来学习一下 浏览器相关知识
浏览器内核和渲染引擎
常见的浏览器内核有哪些
- Trident内核:IE,360,搜狗浏览器等。[又称MSHTML]
- Presto内核:Opera7及以上。[Opera内核原为:Presto,现为:Blink;]
- Webkit内核:Safari,Chrome等。[ Chrome的Blink(WebKit的分支)]
为什么我们需要知道一些基本的浏览器内核 ? 因为所有网页浏览器、电子邮件客户端以及其它需要显示网络内容的应用程序都需要内核
浏览器渲染引擎有人说是 Css 引擎和 Js 引擎,其实具体点应该是渲染引擎和Js引擎,为什么这么说,因为浏览器在渲染一个网页时,一般有三步
- 浏览器通过 HTMLParser 把 HTML 解析成 DOM Tree (俗称DOM树)。
- 浏览器通过 CSSParser 把 CSS 解析成 CSS Rule Tree(俗称CSSOM树)。
- 浏览器将 JavaScript 通过 DOM API 或者 CSSOM API 将 JS 代码解析并应用到布局中,根据 DOM 树和 CSSOM 树来构造 Render Tree(Rander 树)
最终的 Rander 树就是整个页面的文档结构抽象表示,然后按要求呈现响应的结果,所以结合这三步来分析,单纯的 Css 渲染引擎从字面的意思上来讲,并不能完全表达前两步
- 渲染引擎
- Js引擎
渲染引擎:主要负责取得网页的内容(HTML、XML、图像等等)、以及计算网页的显示方式,然后会输出至浏览器,浏览器的内核的不同对于网页的语法解释会有不同,所以渲染的效果也不相同
JS引擎:主要负责解析和执行javascript代码来实现网页的动态效果
本地储存
- cookie
- sessionStorage
- localStorage
通过一个表格来对比一下
特性 | cookie | localStorage | sessionStorage |
---|---|---|---|
生命周期 | 一般由服务器生成,可以设置过期时间 | 持久存储 | 当前会话层存储,关闭即清除 |
数据存储大小 | 4K | 5M | 5M |
是否跨域 | 同源 http 请求中携带 , 默认不允许跨域 ,跨域需要设置withCredentials = true ,服务器端需要允许 |
默认不允许跨域,可以使用 postMessage 解决 | cros |
存储位置 | 服务器端,每次请求会携带存放在 header 中 | 硬盘 | 内存 |
关于 cookie 部分属性还需要注意一下安全性
- value 如果用于保存用户登录状态,应该将该值加密
- http-only 不能通过 Js 访问 Cookie,减少 XSS攻击
- secure 只能在协议为 HTTPS 的请求中携带
- same-site 规定浏览器不能在跨域请求中携带 Cookie,减少 CSRF 攻击
浏览器缓存
简单来说,浏览器缓存其实就是浏览器把HTTP获取的资源存储在本地的一种行为
缓存的优先级
- 先在内存中查找
- 如果内存中不存在,则在硬盘中查找
- 如果硬盘中也没有,那么就进行网络请求
- 请求获取的资源缓存到硬盘和内存
缓存分类
- 强缓存
- 协商缓存
先来捋一捋逻辑
- 当客户端请求某个资源时,会先根据这个资源的 http header 判断它是否命中强缓存,如果命中,则直接从本地获取缓存资源,不会发请求到服务器
- 当没有命中强缓存时,客户端会发送请求到服务器,服务器通过 request header 验证这个资源是否命中协商缓存,如果命中,服务器将返回 304,告诉客户端从缓存中获取
- 当协商缓存也没命中时,服务器就会将资源返回客户端
- 当 ctrl+f5 强制刷新网页时,直接从服务器加载,跳过强缓存和协商缓存
- 当 f5 刷新网页时,跳过强缓存,但是会检查协商缓存
强缓存
- Expires(是 http1.0 时的规范,值为一个绝对时间的 GMT 格式的时间字符串,代表缓存资源的过期时间)
- Cache-Control:max-age(是 http1.1的规范,强缓存利用其 max-age 值来判断缓存资源的最大生命周期,它的值单位为秒)
Cache-Control 还有一些常用其它属性:
- no-cache:需要进行协商缓存,发送请求到服务器确认是否使用缓存。
- no-store:禁止使用缓存,每一次都要重新请求数据。
- public:可以被所有的用户缓存,包括终端用户和CDN等中间代理服务器。
- private:只能被终端用户的浏览器缓存,不允许CDN等中间代理服务器对其缓存。
Cache-Control 与 Expires 可以在服务端配置同时启用,同时启用的时候 Cache-Control 优先级高
强缓存缺点
缓存过期之后,不管资源有没有发生改变,都会重新发请求获取资源,而我们希望是在资源文件没有变化的情况下,即使过期了也不重新获取资源,继续使用旧资源,所以就有了协商缓存
协商缓存
- Last-Modified / If-Modified-Since
Last-Modified 值为资源最后更新时间 GMT 格式的时间
,随服务端 response 返回, 当浏览器再次请求该资源时,request 请求头中会包含 If-Modified-Since,该值为缓存之前返回的 Last-Modified,服务器收到 If-Modified-Since 后,根据资源的最后修改时间判断是否命中协商缓存
- ETag / If-None-Match
ETag 表示资源内容的唯一标识 一串数字码
,随服务器端 response 返回,服务器通过比较请求头部的 If-None-Match 与当前资源的 ETag 是否一致来判断资源是否在两次请求之间有过修改,如果没有修改,则命中协商缓存
有了 Last-Modified / If-Modified-Since 为什么还需要 ETag / If-None-Match ?
因为如果本地打开了缓存文件,即使没有对文件进行修改或者在一定周期内做了修改又改了回来,结果都会造成 Last-Modified 被修改,服务器端不能命中缓存
结论
- 强缓存优先级高与协商缓存
- 只要使用缓存,服务器均不会返回资源
- 强缓存不会发送请求到服务器
- 协商缓存会发送请求到服务起
Http 网络请求类型
- Get: 发送请求,获取服务器数据
- Post:向URL指定的资源提交数据
- Put:向服务器提交数据,以修改数据
- Head:请求页面的首部,获取资源的元信息
- Delete:删除服务器上的某些资源。
- Connect:建立连接隧道,用于代理服务器;
- Options:列出可对资源实行的请求方法,常用于跨域
常见 Get 和 Post 区别
- Get 把参数包含在 URL 中,用 & 符号连接起来,POST 则是通过 request body 传递参数
- Get 请求会被主动缓存 Cache, POST 请求不会,除非手动设置
- Post 比 Get 相对安全些,Get 请求在浏览器支持无感回退, Post 则会再次请求
- Get 请求参数会被完整保留在浏览历史记录里,Post 中的参数不会被保留
- Get 请求在URL中传送的参数是有长度限制的,Post 则没有限制
- Get 请求只能使用 URL 编码,Post 可以使用其它类型编码
网络请求状态码
基本分为5类
- 1xx (信息性状态码)接受的请求正在处理
- 2xx (成功状态码) 请求正常处理完毕
- 3xx (重定向) 需要进行附加操作以完成请求
- 4xx (客户端错误) 客户端请求出错,服务器无法处理请求
- 5xx (服务器错误) 服务器处理请求出错
常见状态码:
- 200 请求成功,表示正常返回信息
- 301 永久重定向,会缓存,表示该请求 URL 永久发生了变化,此后以新的 URL 为准
- 302 临时重定向,不会缓存,表示本次请求 URL 临时有变
- 304 常见于 Get 方法使用了协商缓存,服务器满足条件返回的状态码
- 400 请求错误
- 401 需要认证,一般指没有权限,常见于需要 Token
- 403 服务器禁止访问
- 404 找不到与请求 URL 匹配的资源
- 500 常见的服务器端错误
- 503 表示服务器负载,无法处理请求
Http1.0, Http1.1, Http2.0 区别
Http 1.0
- HTTP 1.0 规定浏览器与服务器只保持短连接,浏览器的每次请求都需要与服务器建立一个TCP连接,服务器完成请求处理后即断开TCP连接。它也可以强制开启长链接,例如设置
Connection: keep-alive
字段
Http 1.1
- 引入了长连接,同时使用了管道机制(pipelining),在同一个TCP连接里面,客户端可以同时发送多个请求(
Http管道机制是将多个Http请求(request)批量提交的技术,在传送过程中不需等待服务端的回应,并且只有 GET 和 HEAD 等请求方式可以进行管线化
) - 缓存处理,引入了
Cache-Control
、Etag/If-None-Match
等 - 新增了一些错误状态响应码
Http 2
- 采用了多路复用,即在一个连接里,客户端和浏览器都可以同时发送多个请求或回应,而且不用按照顺序一一对应。
- 允许服务器主动向客户端推送资源
Http 与 Https
Http 是超文本传输协议,基于 Tcp/Ip 通信协议来传递数据
- 请求信息明文传输,容易被窃听捕获
- 数据的完整性未校验,容易被篡改
- 没有验证身份,存在安全性
Https 可以理解为是 Http + ssl 安全套阶层协议, 通过 SSL 证书来验证服务器的身份,并为浏览器和服务器之间的传输数据进行加密(对称 + 非对称)
那它们有什么区别
- 数据是否加密: Http 是明文传输,HTTPS是密文
- 默认端口: Http默认端口是80,Https默认端口是443
- 资源消耗:和HTTP通信相比,Https通信会消耗更多的CPU和内存资源,因为需要加解密处理
- 安全性: http不安全,https相对安全
Https 流程又是怎样的,就是用 SSL 对数据进行加密解密,然后再利用 Http 传输协议进行数据传输(密文),具体逻辑是这样的
当用户在浏览器里输入一个https url,然后会默认连接到服务器的443端口
服务器必须要有一套数字证书,也就是上边说的 SSL (安全套阶层协议),这套证书其实就是一对公钥和私钥(一般需要申请)
服务器会将自己的数字证书(含有公钥)返回给客户端
客户端收到服务器端的数字证书之后,会对其进行验证,如果证书没问题,则会生成一个密钥(对称加密),用证书的公钥对它加密
客户端会发起 HTTPS 中的第二个 HTTP 请求,将加密之后的客户端密钥发送给服务器
服务器接收到客户端发来的密文之后,会用自己的私钥对其进行非对称解密,解密之后得到客户端密钥,然后用客户端密钥对返回数据进行对称加密,这样数据就变成了密文
服务器将加密后的密文返回给客户端
客户端收到服务器发返回的密文,用自己的密钥(客户端密钥)对其进行对称解密,得到服务器返回的数据
Tcp 三次握手和四次挥手
在聊 Tcp 传输协议前,我们先来了解一下 Tcp 报文, 在网上找了一张图,详细请查看
TCP 三次握手和四次挥手需要用到的报文信息,我在图里边做了备注,这些是需要做个简单了解的,然后再通过两张图来了解一下 Tcp 三次握手和四次挥手
三次握手
- 首先三次握手是由客户端发起的,向服务端发起创建一个 Tcp 链接,此时将标志位 SYN 位置 1,并携带一个请求序列号 seq = x
序列号 x 是 32 位,随机生成的 (面向客户端)
- 服务端收到客户端的创建链接请求,那么服务端要做出回应的,所以会将确认标志位 ACK 置 1 ,并生成确认序列号 ack = x + 1
确认序列号是接收的请求序列号 + 1
, 与此同时, 服务端也要向客户端发起一个创建链接请求,将标志位 SYN 位置 1,也携带一个请求序列号 seq = y序列号 y 是 32 位,随机生成的(面向服务端)
- 此时,客户端已经知道服务端收到请求并同意创建链接了,那么自己也需要给服务端一个回应,再次发出请求,也将确认标志位 ACK 置 1 ,并生成确认序列号 ack = y + 1
ok, 通过以上3步,完成了 TCP 三次握手,为什么两次不行 ? 原因很简单,通过前两步,客户端虽然知道可以创建链接了,但是服务端还是一脸懵逼,所以最后一步则是给服务端一个回应,告诉服务端,我也准备好了,可以创建链接了
四次挥手
了解过三次握手的话,那么四次挥手就比较简单了,原理基本相同
- 同理,四次挥手也是由客户端发起的,向服务端发一个断开链接的请求,此时将标志位 FIN 位置 1 ,并携带一个请求序列号 seq = x
- 服务端收到客户端断开连接的请求时,同样要给一个回应,所以会将确认标志位 ACK 置 1,并生成一个确认序列号 ack = x + 1
- 此时,客户端接到(服务端已经收到自己断开链接)的请求了,那么就坐等断开咯,可是服务端可能还有一些事情在处理,例如:返回数据过程中....,所以当服务端处理完手头上的事情了,就会发送一个断开链接的请求到客户端,也就是将 FIN 位置 1 ,并生成一个断开链接的序列号 seq = y
- 客户端收到服务端的断开链接请求了,袄,你也处理完了,那我们就断开吧
ok ,通过以上4步,就完成了 TCP 四次挥手,原理也很简单,就是双向的一问一答
Tcp 和 Udp 的区别
- TCP 是面向连接的协议,也就是说,在收发数据前,必须和对方建立安全可靠的连接(传说中的三次握手 ),而UDP 则是无连接的,只需要目标端口号即可发送数据
- TCP 只支持点对点,而 UDP 则支持一对一,一对多,多对多,多对一都可以
- TCP 传输效率相对较低,因为要创建链接和断开链接,而 UDP 则不需要,所以相对来讲速度快一些
- TCP 面向字节流,UDP面向报文
- TCP 能保证数据正确性,UDP 则可能丢包
前端常见攻防
XSS
csrf
sql 注入
作者:Hisen 来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。