浏览器存储的方式有哪些
特性 | cookie | localStorage | sessionStorage | indexedDB |
---|---|---|---|---|
数据生命周期 | 一般由服务器生成,可以设置过期时间 | 除非被清理,否则一直存在 | 页面关闭就清理 | 除非被清理,否则一直存在 |
数据存储大小 | 4K | 5M | 5M | 无限 |
与服务端通信 | 每次都会携带在 header,中,对于请求性能影响 | 不参与 | 不参与 | 不参与 |
补充:cookie 原本并不是用来储存的,而是用来与服务端通信的,需要存取请自行封装 api。
而 localStorage 则自带 getItem 和 setItem 方法,使用很方便。
localStorage 注意点:
- localStorage 只能存字符串,存取 JSON 数据需配合 JSON.stringify() 和 JSON.parse()
- 遇上禁用 setItem 的浏览器,需要使用 try...catch 捕获异常
对前后端跨域可以说一下吗?如何解决跨域的?
九种跨域方式实现原理
如何跨域我们已经明白了,如果这样问:浏览器没有同源策略会有什么危险?是不是有点瞬间懵逼?
下面是摘选的事例,参考:AJAX跨域访问被禁止的原因
假设有一个黑客叫做小黑,他从网上抓取了一堆美女图做了一个网站,每日访问量爆表。
为了维护网站运行,小黑挂了一张收款码,觉得网站不错的可以适当资助一点,可是无奈伸手党太多,小黑的网站入不敷出。
于是他非常生气的在网页中写了一段js代码,使用ajax向淘宝发起登陆请求,因为很多数人都访问过淘宝,所以电脑中存有淘宝的cookie,不需要输入账号密码直接就自动登录了,然后小黑在ajax回调函数中解析了淘宝返回的数据,得到了很多人的隐私信息,转手一卖,小黑的网站终于盈利了。
如果跨域也可以发送AJAX请求的话,小黑就真的获取到了用户的隐私并成功获利了!!!
浏览器 cookie 和 session 的认识。
session 是基于 cookie 实现的。cookie 保存在客户端浏览器中,而 session 保存在服务器上。cookie 机制是通过检查客户身上的“通行证”来确定客户身份的话,那么 session 机制就是通过检查服务器上的“客户明细表”来确认客户身份。session 相当于程序在服务器上建立的一份客户档案,客户来访的时候只需要查询客户档案表就可以了。
cookie 和 session 的区别:
- 存在的位置:
cookie 存在于客户端,临时文件夹中;session 存在于服务器的内存中,一个 session 域对象为一个用户浏览器服务 - 安全性
cookie 是以明文的方式存放在客户端的,安全性低,可以通过一个加密算法进行加密后存放;session 存放于服务器的内存中,所以安全性好 - 生命周期(以 20 分钟为例)
cookie 的生命周期是累计的,从创建时,就开始计时,20 分钟后 cookie 生命周期结束;
session 的生命周期是间隔的,从创建时,开始计时如在 20 分钟,没有访问 session,那么 session 生命周期被销毁。但是,如果在 20 分钟内(如在第 19 分钟时)访问过 session,那么,将重新计算 session 的生命周期。关机会造成 session 生命周期的结束,但是对 cookie 没有影响 - 访问范围
cookie 为多个用户浏览器共享;session 为一个用户浏览器独享
输入URL发生什么?
- DNS 域名解析(域名解析成ip地址,走UTP协议,因此不会有握手过程):浏览器将 URL 解析出相对应的服务器的 IP 地址(1. 本地浏览器的 DNS 缓存中查找 2. 再向系统DNS缓存发送查询请求 3. 再向路由器DNS缓存 4. 网络运营商DNS缓存 5. 递归搜索),并从 url 中解析出端口号
- 浏览器与目标服务器建立一条 TCP 连接(三次握手)
- 浏览器向服务器发送一条 HTTP 请求报文
- 服务器返回给浏览器一条 HTTP 响应报文
- 浏览器进行渲染
- 关闭 TCP 连接(四次挥手)
浏览器渲染的步骤
- HTML 解析出 DOM Tree
- CSS 解析出 Style Rules
- 两者关联生成 Render Tree
- Layout(布局)根据 Render Tree 计算每个节点的信息
-
Painting 根据计算好的信息进行渲染整个页面
浏览器解析文档的过程中,如果遇到 script 标签,会立即解析脚本,停止解析文档(因为 JS 可能会改变 DOM 和 CSS,如果继续解析会造成浪费)。
如果是外部 script, 会等待脚本下载完成之后在继续解析文档。现在 script 标签增加了 defer 和 async 属性,脚本解析会将脚本中改变 DOM 和 css 的地方> 解析出来,追加到 DOM Tree 和 Style Rules 上
页面渲染优化
基于对渲染过程的了解,推荐一下优化:
- HTML 文档结构层次尽量少,最好不深于 6 层
- 脚本尽量放后边,避免组织页面加载
- 少量首屏样式可以放在便签内
- 样式结构层次尽量简单
- 脚本减少 DOM 操作,减少回流,尽量缓存访问 DOM 的样式信息
- 尽量减少 JS 修改样式,可以通过修改 class 名的方式解决
- 减少 DOM 查找,缓存 DOM 查找结果
- 动画在屏幕外或页面滚动时,尽量停止
强制缓存和协商缓存
强制缓存是我们在第一次请求资源时在 http 响应头设置一个过期时间,在时效内都将直接从浏览器进行获取,常见的 http 响应头字段如 Cache-Control 和 Expires
协商缓存是我们通过 http 响应头字段 etag 或者 Last-Modified 等判断服务器上资源是否修改,如果修改则从服务器重新获取,如果未修改则 304 指向浏览器缓存中进行获取
GET 和 POST 请求的区别
- GET 参数通过 url 传递,POST 放在 body 中。(http 协议规定,url 在请求头中,所以大小限制很小)
- GET 请求在 url 中传递的参数是有长度限制的,而 POST 没有。原因见上↑↑↑
- GET 在浏览器回退时是无害的,而 POST 会再次提交请求
- GET 请求会被浏览器主动 cache,而 POST 不会,除非手动设置
- GET 比 POST 更不安全,因为参数直接暴露在 url 中,所以不能用来传递敏感信息
- 对参数的数据类型,GET 只接受 ASCII字符,而 POST 没有限制
- GET 请求只能进行 url(x-www-form-urlencoded)编码,而 POST 支持多种编码方式
- GET 产生一个 TCP 数据包;POST 产生两个 TCP 数据包。对于 GET 方式的请求,浏览器会把 http 的 header 和 data 一并发送出去,服务器响应200(返回数据)。而对于 POST,浏览器先发送 header,服务器响应100 continue,浏览器再发送 data,服务器响应200 ok(返回数据)
HTTP1.0 / 1.1 / 2.0 及HTTPS
你需要知道的HTTP常识
可能是全网最全的http面试答案
如何优雅的谈论HTTP/1.0/1.1/2.0
HTTP1.1 是当前使用最为广泛的HTTP协议
- HTTP1.0 和 HTTP1.1 相比
- 缓存处理:在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。
- 带宽优化及网络连接的使用:HTTP1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP1.1则在请求头引入了range头域,它允许只请求资源的某个部分,即返回码是206(Partial Content),这样就方便了开发者*的选择以便于充分利用带宽和连接。
- 错误通知的管理:在HTTP1.1中新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。
- Host头处理:在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。HTTP1.1的请求消息和响应消息都应支持Host头域,且请求消息中如果没有Host头域会报告一个错误(400 Bad Request)。
- 长连接:HTTP 1.1支持长连接(PersistentConnection)和请求的流水线(Pipelining)处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,在HTTP1.1中默认开启Connection: keep-alive,一定程度上弥补了HTTP1.0每次请求都要创建连接的缺点。通过设置http的请求头部和应答头部,保证本次数据请求结束之后,下一次请求仍可以重用这一通道,避免重新握手。
- HTTP2.0 和 HTTP1.X 相比
- 新的二进制格式(Binary Format):HTTP1.x的解析是基于文本。基于文本协议的格式解析存在天然缺陷,文本的表现形式有多样性,要做到健壮性考虑的场景必然很多,二进制则不同,只认0和1的组合。基于这种考虑HTTP2.0的协议解析决定采用二进制格式,实现方便且健壮。
- 多路复用(MultiPlexing):即连接共享,即每一个request都是是用作连接共享机制的。一个request对应一个id,这样一个连接上可以有多个request,每个连接的request可以随机的混杂在一起,接收方可以根据request的 id将request再归属到各自不同的服务端请求里面。
- header压缩:如上文中所言,对前面提到过HTTP1.x的header带有大量信息,而且每次都要重复发送,HTTP2.0使用了专门为首部压缩而设计的 HPACK 算法,使用encoder来减少需要传输的header大小,通讯双方各自cache一份header fields表,既避免了重复header的传输,又减小了需要传输的大小。
- 服务端推送(server push):服务端推送能把客户端所需要的资源伴随着index.html一起发送到客户端,省去了客户端重复请求的步骤。正因为没有发起请求,建立连接等操作,所以静态资源通过服务端推送的方式可以极大地提升速度。例如我的网页有一个sytle.css的请求,在客户端收到sytle.css数据的同时,服务端会将sytle.js的文件推送给客户端,当客户端再次尝试获取sytle.js时就可以直接从缓存中获取到,不用再发请求了。
- HTTPS 与 HTTP 相比
- HTTPS协议需要到CA申请证书,一般免费证书很少,需要交费。
- HTTP协议运行在TCP之上,所有传输的内容都是明文,HTTPS运行在SSL/TLS之上,SSL/TLS运行在TCP之上,所有传输的内容都经过加密的。
- HTTP和HTTPS使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
- HTTPS可以有效的防止运营商劫持,解决了防劫持的一个大问题。
HTTPS 介绍:HTTPS在传输数据之前需要客户端(浏览器)与服务端(网站)之间进行一次握手,在握手过程中将确立双方加密传输数据的密码信息。TLS/SSL协议不仅仅是一套加密传输的协议,TLS/SSL中使用了非对称加密,对称加密以及HASH算法。
握手过程的简单描述如下:
1.浏览器将自己支持的一套加密规则发送给网站。
2.网站从中选出一组加密算法与HASH算法,并将自己的身份信息以证书的形式发回给浏览器。证书里面包含了网站地址,加密公钥,以及证书的颁发机构等信息。
3.获得网站证书之后浏览器要做以下工作:
a. 验证证书的合法性(颁发证书的机构是否合法,证书中包含的网站地址是否与正在访问的地址一致等),如果证书受信任,则浏览器栏里面会显示一个小锁头,否则会给出证书不受信的提示。
b. 如果证书受信任,或者是用户接受了不受信的证书,浏览器会生成一串随机数的密码,并用证书中提供的公钥加密。
c. 使用约定好的HASH计算握手消息,并使用生成的随机数对消息进行加密,最后将之前生成的所有信息发送给网站。
4.网站接收浏览器发来的数据之后要做以下的操作:
a. 使用自己的私钥将信息解密取出密码,使用密码解密浏览器发来的握手消息,并验证HASH是否与浏览器发来的一致。
b. 使用密码加密一段握手消息,发送给浏览器。
5.浏览器解密并计算握手消息的HASH,如果与服务端发来的HASH一致,此时握手过程结束,之后所有的通信数据将由之前浏览器生成的随机密码并利用对称加密算法进行加密。
这里浏览器与网站互相发送加密的握手消息并验证,目的是为了保证双方都获得了一致的密码,并且可以正常的加密解密数据。其中非对称加密算法用于在握手过程中加密生成的密码,对称加密算法用于对真正传输的数据进行加密,而HASH算法用于验证数据的完整性。由于浏览器生成的密码是整个数据加密的关键,因此在传输的时候使用了非对称加密算法对其加密。非对称加密算法会生成公钥和私钥,公钥只能用于加密数据,因此可以随意传输,而网站的私钥用于对数据进行解密,所以网站都会非常小心的保管自己的私钥,防止泄漏。TLS握手过程中如果有任何错误,都会使加密连接断开,从而阻止了隐私信息的传输。正是由于HTTPS非常的安全,攻击者无法从中找到下手的地方,于是更多的是采用了假证书的手法来欺骗客户端,从而获取明文的信息。
介绍下304过程
a. 浏览器请求资源时首先命中资源的Expires 和 Cache-Control,Expires 受限于本地时间,如果修改了本地时间,可能会造成缓存失效,可以通过Cache-control: max-age指定最大生命周期,状态仍然返回200,但不会请求数据,在浏览器中能明显看到from cache字样。
b. 强缓存失效,进入协商缓存阶段,首先验证ETagETag可以保证每一个资源是唯一的,资源变化都会导致ETag变化。服务器根据客户端上送的If-None-Match值来判断是否命中缓存。
c. 协商缓存Last-Modify/If-Modify-Since阶段,客户端第一次请求资源时,服务服返回的header中会加上Last-Modify,Last-modify是一个时间标识该资源的最后修改时间。再次请求该资源时,request的请求头中会包含If-Modify-Since,该值为缓存之前返回的Last-Modify。服务器收到If-Modify-Since后,根据资源的最后修改时间判断是否命中缓存。
HTTP 状态码
-
1xx(临时响应)表示临时响应并需要请求者继续执行操作的状态码
- 100 - 继续 请求者应当继续提出请求。服务器返回此代码表示已收到请求的第一部分,正在等待其余部分
- 101 - 切换协议 请求者已要求服务器切换协议,服务器已确认并准备切换
-
2xx(成功)表示成功处理了请求的状态码
- 200 - 成功 服务器已经成功处理了请求。通常,这表示服务器提供了请求的网页
- 201 - 已创建 请求成功并且服务器创建了新的资源
- 202 - 已接受 服务器已接受请求,但尚未处理
- 203 - 非授权信息 服务器已经成功处理了请求,但返回的信息可能来自另一来源
- 204 - 无内容 服务器成功处理了请求,但没有返回任何内容
- 205 - 重置内容 服务器成功处理了请求,但没有返回任何内容
- 206 - 部分内容 服务器成功处理了部分GET请求
-
3xx(重定向)表示要完成请求,需要进一步操作;通常,这些状态代码用来重定向
- 300 - 多种选择 针对请求,服务器可执行多种操作。服务器可根据请求者(user agent)选择一项操作,或提供操作列表供请求者选择
- 301 - 永久移动 请求的网页已永久移动到新位置。服务器返回此响应(对GET或HEAD请求的响应)时,会自动将请求者转到新位置
- 302 - 临时移动 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求
- 303 - 查看其它位置 请求者应当对不同的位置使用单独的GET请求来检索响应时,服务器返回此代码
- 304 - 未修改 自上次请求后,请求的网页未修改过。服务器返回此响应,不会返回网页的内容
- 305 - 使用代理 请求者只能使用代理访问请求的网页。如果服务器返回此响应,还表示请求者应使用代理
- 307 - 临时性重定向 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有的位置来进行以后的请求
-
4xx(请求错误)这些状态码表示请求可能出错,妨碍了服务器的处理
- 400 - 错误请求 服务器不理解请求的语法
- 401 - 未授权 请求要求身份验证。对于需要登录的网页,服务器可能返回此响应
- 403 - 禁止 服务器拒绝请求
- 404 - 未找到 服务器找不到请求的网页
- 405 - 方法禁用 禁用请求中指定的方法
- 406 - 不接受 无法使用请求的内容特性响应请求的网页
- 407 - 需要代理授权 此状态码与401(未授权)类似,但指定请求者应当授权使用代理
- 408 - 请求超时 服务器等候请求时发生超时
- 409 - 冲突 服务器在完成请求时发生冲突。服务器必须在响应中包含有关冲突的信息
- 410 - 已删除 如果请求的资源已永久删除,服务器就会返回此响应
- 411 - 需要有效长度 服务器不接受不含有效内容长度标头字段的请求
- 412 - 未满足前提条件 服务器未满足请求者在请求者设置的其中一个前提条件
- 413 - 请求实体过大 服务器无法处理请求,因为请求实体过大,超出了服务器的处理能力
- 414 - 请求的URI过长 请求的URI(通常为网址)过长,服务器无法处理
- 415 - 不支持媒体类型 请求的格式不受请求页面的支持
- 416 - 请求范围不符合要求 如果页面无法提供请求的范围,则服务器会返回此状态码
- 417 - 未满足期望值 服务器未满足“期望”请求标头字段的要求
-
5xx(服务器错误)这些状态码表示服务器在尝试处理请求时发生内部错误。这些错误可能是服务器本身的错误,而不是请求出错
- 500 - 服务器内部错误 服务器遇到错误,无法完成请求
- 501 - 尚未实施 服务器不具备完成请求的功能。例如,服务器无法识别请求方法时可能会返回此代码
- 502 - 错误网关 服务器作为网关或代理,从上游服务器无法收到无效响应
- 503 - 服务器不可用 服务器目前无法使用(由于超载或者停机维护)。通常,这只是暂时状态
- 504 - 网关超时 服务器作为网关代理,但是没有及时从上游服务器收到请求
- 505 - HTTP版本不受支持 服务器不支持请求中所用的HTTP协议版本