网络相关

零碎不系统,仅供参考,不能保证精准度和时效性

  1. 从输入 URL 到页面呈现出来的过程

  2. ...

~~~~~~~ 基础知识 ~~~~~~

URL 和 URI 的区别

URI: Uniform Resource Identifier, 统一资源标识符

  • 用唯一的标识来确定一个资源,是一种抽象的定义

  • 即不管用什么方法来定义,只要能唯一地标识一个资源,就可以称为 URI

URL 和 URN 是 URI 的子集。

  • URL: Uniform Resource Location, 统一资源定位符

    • 可以理解为使用地址来标识资源

  • URN: Uniform Resource Name, 统一资源名称

跨域
  1. 同源 vs 跨域

    • origin: 协议+域名+端口

  2. 同源策略的限制 (???)

    • cookie, localStorage, IndexDB 无法读取

    • DOM 和 JS 对象无法获得

    • AJAX 请求不能发送

  3. 跨域解决方案

    • JSONP, postMessage

    • CORS

    • document.domain

    • ....

P20

跨域,是指浏览器不能执行其它网站的脚本。它是由浏览器的同源策略造成的,是浏览器对 JavaScript 实施的安全限制,那么只要协议、域名、端口有任何一个不同,都被当作是不同的域。 跨域原理,即是通过各种方式,避开浏览器的安全限制。

JS 实现跨域的方法,https://segmentfault.com/a/1190000011145364

JSONP

JSONP 能实现跨域,它是利用标签不受同源策略限制的特性(这算是一个漏洞)。

  1. 浏览器用 JavaScript 代码动态创建一个 <script> 标签,其 src 属性引用第三方的 API 地址,并提供一个回调函数的 function name

    • 比如 https://www.smartstudy.com/api/?callback=functionName

    • 其中的 query 都是约定好了,比如 callbackfunctionName

  2. 后端通过 query 取到函数名,然后把需要的数据以参数的形式传递给该函数,返回给浏览器

  3. 浏览器解析服务器返回的数据,执行该回调函数

JSONP 并不使用 XMLHttpRequest 对象加载数据,而是通过 <script> 标签把资源当做普通的 JavaScript 脚本来加载,所以不存在跨域的问题,也不是真正的 AJAX。

CORS vs JSONP

CORS 可以用作 JSONP 模式的现代替代方案:

  • JSONP 仅支持 GET 方法,而 CORS 还支持其它类型的 HTTP 请求

  • CORS 让程序员可以使用常规的 XMLHttpRequest,它支持比 JSONP 更好的错误处理

  • JSONP 可能会导致跨站点脚本 XSS 问题(在外部站点受到威胁时),而 CORS 允许网站手动解析响应以提高安全性

JSONP 的主要优点是兼容 CORS 出现之前的老版浏览器。现在大多数现代 Web 浏览器都支持 CORS。

客户端存储

cookie, sessionStorage, localStorage, indexdDB

共同点:都保存在浏览器端,且都是同源的

  1. 是否在 HTTP 中携带

    1. cookie 数据会始终在同源的 HTTP 请求中携带(即使不需要),即在浏览器和服务器之间来回传递

      • 所以它的容量较小,大约 4K 左右

      • 所以只适合保存很小的数据,比如会话标识

      • 初衷就是为了弥补 HTTP 的无状态

    2. sessionStorage 和 localStorage 仅在本地保存,不参与和服务器的通信

  2. 是否持久化保存

    1. cookie:在设置的 cookie 过期时间之前一直有效(即使窗口或浏览器关闭了),否则默认为关闭浏览器后失效

      • cookie 还可以限制只属于某个 path 下

    2. sessionStorage:仅在当前“浏览器”窗口关闭前有效(不持久)

      • session,会话,两个页签打开同一个页面,也被视为同一个会话

    3. localStorage:持久化存储(即使窗口或浏览器关闭了),除非被手动清除

  3. 存储空间

    1. cookie,4K 左右

    2. sessionstorage 和 localStorage,5M 左右

  4. 易用性

    1. cookie 原生的接口不太友好,需要自己封装

    2. 其它:可采用原生接口,也可自己封装

  5. 应用场景

    1. cookie

Web 性能优化

检测页面的加载时间,一般有两种方式:

  1. 被动去测:在被检测的页面置入脚本或探针,当用户访问网页时,探针自动采集数据并传回数据库进行分析(数据更真实)

  2. 主动监测:主动搭建分布式受控环境,模拟用户发起页面访问请求,主动采集性能数据并分析。在检测的精准度上,专业的第三方工具效果更佳,比如说性能极客

优化手段:

  1. 内存溢出

  2. 降低请求量:合并资源,减少 HTTP 请求数,minify/gzip 压缩,webP,lazyLoad

  3. 加快请求速度:预解析 DNS,减少域名数,并行加载,CDN 分发,避免重定向

  4. 缓存:HTTP 协议缓存请求,离线缓存 manifest,离线数据缓存 localStorage

  5. 渲染:JS/CSS 优化,动画绘制频率,加载顺序,服务端渲染,pipeline

<script> 的 async 和 sync

~~~~~~ HTTP 相关 ~~~~~

HTTP 请求的方法

最常见:

  1. GET 从指定的资源请求数据

  2. POST 向指定的资源提交要被处理的数据

次常见:

  1. HEAD:类似于 GET 请求,只是返回的响应中没有具体内容,客户端读取响应的 Headers

  2. OPTIONS:允许客户端查看服务器的性能,比如服务器支持的请求方式等

不太常见的:

  1. PUT

  2. DELETE

  3. TRACE

  4. CONNECT

get 和 post 的区别

GET vs POST

  1. 参数位置:在 URL 里 vs 在 request body 中

    • 只能 URL 编码 vs 多种编码方式

    • GET 的参数有长度限制,而 POST 没有

      • 一般限制在 2~8K 之间,常见的是 1K 之内

    • POST 的参数更安全,所以更适合传递一些敏感信息

  2. 浏览器的不同处理

    • GET 请求会被浏览器主动 cache

    • GET 请求参数会被完整地保留在浏览历史记录里

  3. TCP 数据包

    • GET 请求产生一个 TCP 数据包

      • 浏览器会把 HTTP Header 和 data 一起发出去,服务器响应 200

    • POST 产生两个 TCP 数据包

      • 浏览器先发送 header,服务器响应 100 continue

      • 浏览器再发送 data,服务器响应 200 ok

GET 和 POST 的底层都是 TCP/IP,都是 TCP 连接,并无差别。只是由于 HTTP 的规定以及浏览器和服务器的限制,导致它们在使用上有些不同。

get 请求传参长度的误区

误区:我们常说 get 请求参数的大小存在限制,而 post 请求的参数大小是无限制的。

  • HTTP 协议从未规定 get 和 post 请求的长度限制

  • 而是浏览器和 web 服务器限制了 get 请求的参数长度

  • 不同的浏览器和 web 服务器,限制的最大长度不一样

    • 要支持 IE,则最大长度为 2083byte

    • 若只支持 Chrome,则最大长度 8182byte

HTTP 返回的状态码

HTTP Header

可以将 HTTP Header 分为:

  1. 通用首部:表示一些通用信息。比如:

    • date 表示报文创建时间

  2. 请求首部:请求报文中独有的。比如:

    • cookie 相关的 if-Modified-Since

  3. 响应首部:响应报文中独有的。比如:

    • set-cookie

    • location 重定向相关

  4. 实体首部:用来描述实体部分。比如:

    • allow 用来描述可执行的请求方法

    • content-type 描述主题类型

    • content-Encoding 描述主体的编码方式

一个 TCP 连接能发几个 HTTP 请求?
  1. HTTP 1.0,一个 TCP 发送一个 HTTP 请求

    • 一般情况,不支持长连接,在每次请求发送完毕之后 TCP 连接会立即断开

    • 在请求头带上 Connection: Keep-Alive 也可以发送多条,不过有限制

  2. HTTP 1.1,支持长连接,所以只要 TCP 连接不断开,就可以一直发送 HTTP 请求,没有上限

  3. HTTP 2.0

    • 支持长连接。所以只要 TCP 连接不断开,就可以一直发送 HTTP 请求,没有上线

    • 支持多路复用,所以一个 TCP 连接可以并发多个 HTTP 请求

TCP 和 UDP

TCP 是面向连接的可靠性传输,而 UDP 是不可靠的。

TCP vs UDP

  1. 面向连接的 vs 无连接的(发送数据前不需要先建立链接)

  2. 提供可靠服务 vs 尽最大努力交付(不保证可靠交付)

    • 通过 TCP 连接传送的数据,无差错、不丢失、不重复、且按序到达

    • UDP 即便出现网络拥塞也不会降低发送速率,所以会丢包

      • 比如实时应用(电话和视频会议)

  3. 面向字节流 vs 面向报文

  4. 只能是 1 对 1 的 vs 支持 1 对 1, 1 对多

  5. 首部大小:20 字节 vs 只有 8 字节

WebSocket 的实现和应用

WebSocket 是 HTML5 中的协议,支持持久性连接。

  • HTTP 1.0 和 HTTP 1.1 都不支持持久性的连接

  • HTTP 1.1 中的 keep-alive 可以将多个 HTTP 请求合并为一个。

HTTP 的生命周期通过 Request-Response 来界定。一个 Request 只能对应一个 Response,而且这个 Response 是被动的,不能主动发起。

  • 在 HTTP 1.0 协议中,这次 HTTP 请求就结束了

  • 在 HTTP 1.1 中,connection: Keep-alive,就可以在一个 HTTP 连接中,发送多个 Request,接收多个 Response

WebSocket 是基于 HTTP 协议的,或者说借用了 HTTP 协议来完成一部分握手,在握手阶段和 HTTP 是相同的。

看一个 websocket 握手协议的实现,基本是 2 个属性 upgrade, connection

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw== 
Sec-WebSocket-Protocol: chat, superchat 
Sec-WebSocket-Version: 13
Origin: http://example.com
websocket 和 ajax 轮询
  • websocket,HTML5 的新协议,可以实现服务端和服务器的通信,实现服务器的推送功能

    • 优点:只要建立一次连接,就可以连续不断地得到服务器推送的消息,因此节省带宽、减少服务器端的压力

  • ajax 轮询:每隔一段时间(0.5s)就向服务器发起 ajax 请求,以查询服务器是否有数据更新

    • 缺点:每次都要建立 HTTP 连接,因此比较浪费带

HTTP 协议(特征)
  • 基于 TCP/IP 通信协议来传递数据,比如 HTML 文件、图片文件、查询结果

  • 属于应用层的、面向对象的协议

  • 使用简捷、快速,适用于分布式超媒体信息系统

    • 它于 1990 年提出,经过几年的使用与发展,得到不断地完善和扩展

    • 目前在 WWW 中使用的是 HTTP/1.0 的第六版

    • HTTP/1.1 的规范化工作正在进行之中

    • HTTP-NG(Next Generation of HTTP)的建议已经提出

  • HTTP 协议工作于客户端-服务端架构中

    • 浏览器作为 HTTP 客户端,通过 URL 向 HTTP 服务端(WEB 服务器)发送请求

    • Web 服务器根据接收到的请求后,向客户端发送响应信息

HTTP 和 HTTPS 的区别

HTTP,超文本传输协议。基于 TCP/IP 通信协议,用于从 WWW 服务器传输超文本到本地浏览器,它的模式是“一个请求对应一个响应”。

HTTPS 是 HTTP 的安全版,即在 HTTP 下加入 SSL 层。SSL 是 HTTPS 的安全基础,因为 HTTP 传输的数据是明文的(没有加密),而 SSL 协议可以对其数据进行加密。SSL 加密是在传输层实现的。

所以说,HTTPS 比 HTTP 协议的安全性更高,它能进行加密传输和身份认证。

  • SSL 加密

  • CA 证书

此外,HTTP 80端口 vs HTTPS 443端口

HTTPS 的原理和优缺点

工作原理

  • 客户端使用 HTTPS URL 访问服务器

  • 服务器建立 SSL 链接,并将网站的证书(包含了公钥)传给客户端

  • 客户端和服务器端开始协商 SSL 链接的安全等级,并建立会话密钥

  • 然后通过网站的公钥来加密会话密钥并传送给网站

优点

  • 可以认证用户和服务器,确保数据发送到正确的客户机和服务器

  • 更安全,可防止数据在传输过程中被窃取、改变

  • 是现行架构下最安全的解决方案,虽然不是绝对安全,但它大幅增加了中间人攻击的成本

缺点

  • 握手阶段比较费时,会使页面加载时间延长 50%,增加 10%~20%的耗电

  • 缓存不如 HTTP 高效,会增加数据开销

  • SSL 证书需要钱,功能越强大的证书费用越高

  • SSL 证书需要绑定 IP,不能在同一个 IP 上绑定多个域名,ipv4 资源支持不了这种消耗

HTTP 2.0

HTTP 2.0 是基于 HTTPS 的,天然具有安全特性,且它还能避免单纯使用 HTTPS 的性能下降。

  1. 提升访问速度:HTTP 1.0,请求资源所需时间更少、访问速度更快

  2. 多路复用:这相当于是长连接的增强

    • 每个 Request 请求可以随机地混杂在一起,接收方可以根据 Request 的 id 将 Request 再归属到各自不同的服务端请求里面

    • 另外多路复用中也支持了流的优先级,允许客户端告诉服务器那些内容是更优先级的资源,可以优先传输。

    • 在 HTTP 1.1 中,客户端在同一时间针对同一域名下的请求,有数量限制(连接数量),超过限制了会被阻塞

  3. 二进制分帧:

    • HTTP 1.X 的解析是基于文本的

    • HTTP 2.0 将所有的传输信息分割为更小的消息和帧,并对它们采用二进制格式编码

    • 基于二进制可以让协议有更多的扩展性,比如用“帧”来传输数据和指令

  4. 首部压缩

  5. 服务器端推送

~~~~~~~~ 缓存 ~~~~~~~~

缓存机制的 4 个方面

作用:减少网络 IO 消耗,提高访问速度。

浏览器的缓存机制有四个方面,按照获取资源时请求的优先级,依次排列如下:

  1. Memory Cache

  2. Service Worker Cache

  3. HTTP Cache

  4. Push Cache

强缓存、协商缓存

根据响应的 Header 内容来决定:

  1. 强缓存:200 from cache,不发请求到服务器,直接从缓存取

    • 过去用 expires,使用的是基于服务器端的绝对时间(会存在时差)

    • 现在用 Cache-Control,使用相对时间

      • 是一个通用 Header 字段,可用于 HTTP 请求和响应中

      • 该缓存指令是单向的,常见的取值有

        • private 默认

        • no-cache

        • max-age

        • must-revalidate

    • 若两同时存在,则用新的

  2. 协商缓存:304 not modified,发送请求到服务器,通过服务器告知缓存是否可用

    • Last-Modified 时间戳

    • Last-Modified/If-Modified-Since

    • Etag/If-None-Match

在没有命中强缓存的时候,才会走协商缓存。

预期:如果服务器上的资源更新了,那浏览器就请求新资源;否则就用本地缓存。以最大程度地减少因网络请求而产生的资源浪费。

在请求这些有设置缓存的数据时,会先查看是否过期

  • 如果没有过期,则直接使用本地缓存

  • 否则,就向服务器发起请求,并重新协商有关缓存信息

    • 如果上次响应设置了 ETag 值,则会在这次请求的时候作为 If-None-Match 的值交给服务器校验

    • 如果上次响应设置了 Last-Modified 值,则会在这次请求的时候作为 If-Modified-Since 的值交给服务器校验

    • 如果都没有设置,则直接请求

  • 而在需要“服务器校验(协商缓存)”时,它会返回 200304

    • 200 表示这是全新的数据

    • 304 表示从缓存取

说明:两次“从缓存取”,第一次是命中强缓存,第二次是经过与服务器协商且确认缓存未过期。

详情参阅:https://segmentfault.com/a/1190000008956069

get 和 post 请求在缓存方面的区别

缓存一般只适用于那些“不会更新服务端数据”的请求。所以:

  • 一般会对 get 请求进行缓存

  • 很少会对 post 请求进行缓存

ajax 解决浏览器缓存问题
  1. 在 ajax 发送请求前加上 anyAjaxObj.setRequestHeader("If-Modified-Since","0")

  2. 在 ajax 发送请求前加上 anyAjaxObj.setRequestHeader("Cache-Control","no-cache")

  3. 在 URL 后面加上一个随机数: "fresh=" + Math.random()

  4. 在 URL 后面加上时间戳 "nowtime=" + new Date().getTime()

如果是使用 jQuery,直接这样就可以了 $.ajaxSetup({cache:false}),这样页面的所有 ajax 都会执行这条语句就是不需要保存缓存记录。

~~~~~~~~ 更多 ~~~~~~~~

Fetch 发送两次请求的原因

Fetch 发送 POST 请求时,总是发送两次:第一次状态码是 204,第二次才成功。

原因:Fetch 第一次会发送一个 Options 请求,询问服务器是否支持修改的请求头,如果服务器支持,则会在第二次发送真正的请求

CDN

CDN,Content Delivery Network,内容分发网络。

CDN 是一个智能虚拟网络,构建在现有网络的基础之上的。它依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,让用户就近获取所需内容,从而降低网络阻塞、提高用户访问响应速度和命中率。CDN 的关键技术主要:内容存储和分发技术。

CDN 的主要功能:

  1. 节省骨干网带宽,减少带宽请求量

  2. 提供服务器端加速,避免由于用户访问量大而造成服务器过载

  3. 服务商使用 web cach 技术,在本地缓存“用户访问过的 web 页面和对象”

    • 既避免了占用主干的出口带宽

    • 又能缩短用户访问页面的响应时间

  4. 能克服网站分布不均的问题,并且能降低网站自身建设和维护成本

  5. 降低“通信风暴”的影响,从而提高网络访问的稳定性

CDN 的基本原理是:广泛采用各种缓存服务器,将这些缓存服务器分布到用户访问相对集中的地区或网络中,在用户访问网站的时候,利用“全局负载技术”将用户的访问指向距离最近、且工作正常的缓存服务器上,由缓存服务器直接响应用户的请求。

图片的懒加载和预加载
  • 预加载:提前加载图片,当用户需要查看时可直接从本地缓存中渲染

  • 懒加载:迟缓加载,减少请求数或延迟请求数,主要是作为服务器端的优化

访问图片 URL 后直接下载,如何实现?

在请求的返回头里,用于浏览器解析的重要参数就是 OSS 的 API 文档里面的返回 HTTP 头,决定用户下载行为的参数。

x-oss-object-type: Normal
x-oss-request-id: 598D5ED34F29D01FE2925F41
x-oss-storage-class: Standard

Last updated