前端浏览器网络系列进阶(本地储存,缓存,网络,协议,安全)

1,428 阅读14分钟

前言

前端眼里只有 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引擎,为什么这么说,因为浏览器在渲染一个网页时,一般有三步

  1. 浏览器通过 HTMLParser 把 HTML 解析成 DOM Tree (俗称DOM树)。
  2. 浏览器通过 CSSParser 把 CSS 解析成 CSS Rule Tree(俗称CSSOM树)。
  3. 浏览器将 JavaScript 通过 DOM API 或者 CSSOM API 将 JS 代码解析并应用到布局中,根据 DOM 树和 CSSOM 树来构造 Render Tree(Rander 树)

最终的 Rander 树就是整个页面的文档结构抽象表示,然后按要求呈现响应的结果,所以结合这三步来分析,单纯的 Css 渲染引擎从字面的意思上来讲,并不能完全表达前两步

  • 渲染引擎
  • Js引擎

渲染引擎:主要负责取得网页的内容(HTML、XML、图像等等)、以及计算网页的显示方式,然后会输出至浏览器,浏览器的内核的不同对于网页的语法解释会有不同,所以渲染的效果也不相同

JS引擎:主要负责解析和执行javascript代码来实现网页的动态效果

本地储存

  • cookie
  • sessionStorage
  • localStorage

通过一个表格来对比一下

特性cookielocalStoragesessionStorage
生命周期一般由服务器生成,可以设置过期时间持久存储当前会话层存储,关闭即清除
数据存储大小4K5M5M
是否跨域同源 http 请求中携带 , 默认不允许跨域 ,跨域需要设置withCredentials = true,服务器端需要允许默认不允许跨域,可以使用 postMessage 解决cros
存储位置服务器端,每次请求会携带存放在 header 中硬盘内存

关于 cookie 部分属性还需要注意一下安全性

  • value 如果用于保存用户登录状态,应该将该值加密
  • http-only 不能通过 Js 访问 Cookie,减少 XSS攻击
  • secure 只能在协议为 HTTPS 的请求中携带
  • same-site 规定浏览器不能在跨域请求中携带 Cookie,减少 CSRF 攻击

浏览器缓存

简单来说,浏览器缓存其实就是浏览器把HTTP获取的资源存储在本地的一种行为

缓存的优先级

  1. 先在内存中查找
  2. 如果内存中不存在,则在硬盘中查找
  3. 如果硬盘中也没有,那么就进行网络请求
  4. 请求获取的资源缓存到硬盘和内存

缓存分类

  • 强缓存
  • 协商缓存

先来捋一捋逻辑

  1. 当客户端请求某个资源时,会先根据这个资源的 http header 判断它是否命中强缓存,如果命中,则直接从本地获取缓存资源,不会发请求到服务器
  2. 当没有命中强缓存时,客户端会发送请求到服务器,服务器通过 request header 验证这个资源是否命中协商缓存,如果命中,服务器将返回 304,告诉客户端从缓存中获取
  3. 当协商缓存也没命中时,服务器就会将资源返回客户端
  • 当 ctrl+f5 强制刷新网页时,直接从服务器加载,跳过强缓存和协商缓存
  • 当 f5 刷新网页时,跳过强缓存,但是会检查协商缓存

强缓存

  • Expires(是 http1.0 时的规范,值为一个绝对时间的 GMT 格式的时间字符串,代表缓存资源的过期时间)
  • Cache-Control:max-age(是 http1.1的规范,强缓存利用其 max-age 值来判断缓存资源的最大生命周期,它的值单位为秒)

Cache-Control 还有一些常用其它属性:

  1. no-cache:需要进行协商缓存,发送请求到服务器确认是否使用缓存。
  2. no-store:禁止使用缓存,每一次都要重新请求数据。
  3. public:可以被所有的用户缓存,包括终端用户和CDN等中间代理服务器。
  4. 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-ControlEtag/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 报文, 在网上找了一张图,详细请查看

image.png

TCP 三次握手和四次挥手需要用到的报文信息,我在图里边做了备注,这些是需要做个简单了解的,然后再通过两张图来了解一下 Tcp 三次握手和四次挥手

三次握手

image.png

  1. 首先三次握手是由客户端发起的,向服务端发起创建一个 Tcp 链接,此时将标志位 SYN 位置 1,并携带一个请求序列号 seq = x 序列号 x 是 32 位,随机生成的 (面向客户端)
  2. 服务端收到客户端的创建链接请求,那么服务端要做出回应的,所以会将确认标志位 ACK 置 1 ,并生成确认序列号 ack = x + 1 确认序列号是接收的请求序列号 + 1, 与此同时, 服务端也要向客户端发起一个创建链接请求,将标志位 SYN 位置 1,也携带一个请求序列号 seq = y 序列号 y 是 32 位,随机生成的(面向服务端)
  3. 此时,客户端已经知道服务端收到请求并同意创建链接了,那么自己也需要给服务端一个回应,再次发出请求,也将确认标志位 ACK 置 1 ,并生成确认序列号 ack = y + 1

ok, 通过以上3步,完成了 TCP 三次握手,为什么两次不行 ? 原因很简单,通过前两步,客户端虽然知道可以创建链接了,但是服务端还是一脸懵逼,所以最后一步则是给服务端一个回应,告诉服务端,我也准备好了,可以创建链接了

四次挥手

image.png

了解过三次握手的话,那么四次挥手就比较简单了,原理基本相同

  1. 同理,四次挥手也是由客户端发起的,向服务端发一个断开链接的请求,此时将标志位 FIN 位置 1 ,并携带一个请求序列号 seq = x
  2. 服务端收到客户端断开连接的请求时,同样要给一个回应,所以会将确认标志位 ACK 置 1,并生成一个确认序列号 ack = x + 1
  3. 此时,客户端接到(服务端已经收到自己断开链接)的请求了,那么就坐等断开咯,可是服务端可能还有一些事情在处理,例如:返回数据过程中....,所以当服务端处理完手头上的事情了,就会发送一个断开链接的请求到客户端,也就是将 FIN 位置 1 ,并生成一个断开链接的序列号 seq = y
  4. 客户端收到服务端的断开链接请求了,袄,你也处理完了,那我们就断开吧

ok ,通过以上4步,就完成了 TCP 四次挥手,原理也很简单,就是双向的一问一答

Tcp 和 Udp 的区别

  • TCP 是面向连接的协议,也就是说,在收发数据前,必须和对方建立安全可靠的连接(传说中的三次握手 ),而UDP 则是无连接的,只需要目标端口号即可发送数据
  • TCP 只支持点对点,而 UDP 则支持一对一,一对多,多对多,多对一都可以
  • TCP 传输效率相对较低,因为要创建链接和断开链接,而 UDP 则不需要,所以相对来讲速度快一些
  • TCP 面向字节流,UDP面向报文
  • TCP 能保证数据正确性,UDP 则可能丢包

前端常见攻防

XSS

csrf

sql 注入