【前端词典】进阶必备的网络基础(下)

前言

上一篇我提到了前端面试频率较高的几个网络基础知识,这一篇我会把上一篇遗留的五个尽力讲清楚。若是尚未来得及看上一篇,那么如今能够一块儿看。javascript

目录html

接下来我会讲如下内容:前端

  1. 五类 IP 地址
  2. 跨域的缘由及处理方式
  3. 正向代理和反向代理
  4. CDN 带来的性能优化
  5. HTTP 强缓存&协商缓存

五类 IP 地址 TOP java

网络地址:用于识别主机所在的网络;
主机地址:用于识别该网络中的主机。node

IP地址分为五类:nginx

  1. A 类保留给政府机构
  2. B 类分配给中等规模的公司
  3. C 类分配给任何须要的人
  4. D 类用于用于特殊用途. 又称作广播地址
  5. E 类暂时保留

各种可容纳的地址数目不一样。其中A类、B类、和C类这三类地址用于 TCP/IP 节点,其它两类D类和E类被用于特殊用途。web

首先用一张图给你们一个初步的概念: 面试

一. A类地址

第一个八位段为网络地址,其它为主机地址,第一个八位段首位必定为0;
范围:1.0.0.1—126.155.255.254;
私有地址和保留地址:
10.X.X.X是私有地址(所谓的私有地址就是在互联网上不使用,而被用在局域网络中的地址)。
127.X.X.X是保留地址,用作循环测试用的。json

二. B类地址

第一个八位段和第二个八位段为网络地址,其它为主机地址,第一个八位段首位必定为10;
范围:128.0.0.1—191.255.255.254。
私有地址和保留地址:
172.16.0.0—172.31.255.255是私有地址
169.254.X.X是保留地址。若是你的IP地址是自动获取IP地址,而你在网络上又没有找到可用的DHCP服务器。就会获得其中一个IP。segmentfault

三. C类地址

前三个八位段为网络地址,第4个个字节为主机地址,第一个八位段首位必定为110。
范围:192.0.0.1—223.255.255.254。
私有地址:
192.168.X.X是私有地址。

四. D类地址

不分网络地址和主机地址,第一个八位段首位必定为1110。
范围:224.0.0.1—239.255.255.254

五. E类地址

不分网络地址和主机地址,第一个八位段首位必定为11110。
范围:240.0.0.1—255.255.255.254

跨域的缘由及处理方式 TOP

出现跨域的缘由是因为 浏览器的同源策略 所决定的。

同源策略限制了从同一个源加载的文档或脚本如何与来自另外一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。

这个说法一如既往的很官方,犹如女神的一句 呵呵,让人不知因此然。接下来就从 Dom 查询和接口请求来讲明同源策略的必要性。

接口请求(假设没有同源策略)

咱们来看场景:
1.你打开 www.taobao.com,准备购买你已经添加在购物车的《JavaScript 高级程序设计》。
2.当你刚想付款的时候,有一我的发给你一个连接 www.heiheihei.com,你的眼神忽然变得正经了,然后绝不犹豫的点了进去。
3.你很正经的观看 www.heiheihei.com 中的内容,www.heiheihei.com 也没有闲着,因为没有同源策略的限制,它向 www.taobao.com 发起了请求!暗地里随心所欲的作一些随心所欲的事情。

Dom 查询(假设没有同源策略)

1.星期一的早上,你像往常同样点开淘宝,在淘宝里逛起了街,不过今天你没有在乎为何今天须要登录。
2. 为何须要登陆呢?我就假设这是有心之人恶意为之,这个登录页面作了什么呢?我再假设页面有如下代码

// HTML
<iframe name="taobaoo" src="www.taobaoo.com"></iframe>
// JS
// 因为没有同源策略的限制, Dom 能够直接拿到。
const iframe = window.frames['taobaoo'];
const account = iframe.document.getElementById('***')
const pw = iframe.document.getElementById('***')
// 密码帐号被偷走了
复制代码

从上面两种状况,咱们初步了解同源策略确实能规避一些危险,不是说有了同源策略就安全,只是说同源策略是一种浏览器最基本的安全机制,毕竟能提升一点攻击的成本。

跨域解决方案

  1. 经过 jsonp 跨域
  2. document.domain + iframe 跨域
  3. location.hash + iframe
  4. window.name + iframe跨域
  5. postMessage 跨域
  6. 跨域资源共享( CORS )
  7. nginx 代理跨域
  8. nodejs 中间件代理跨域
  9. WebSocket 协议跨域

以上的方法我会挑几个讲

1、JSONP

JSONP 的原理很简单,就是利用 <script> 标签没有跨域限制的漏洞。经过 <script> 标签指向一个须要访问的地址并提供一个回调函数来接收数据当须要通信时。 JSONP 使用简单且兼容性不错,可是只限于 get 请求。

function jsonp(url, jsonpCallback, success) {
  let script = document.createElement('script')
  script.src = url
  script.async = true
  script.type = 'text/javascript'
  window[jsonpCallback] = function(data) {
    success && success(data)
  }
  document.body.appendChild(script)
}
jsonp('http://xxx', 'callback', function(value) {
  console.log(value)
})
复制代码

2、CORS

CORS 须要浏览器和后端同时支持。浏览器会自动进行 CORS 通讯,实现 CORS 通讯的关键是后端。只要后端实现了 CORS,就实现了跨域。 服务端设置 Access-Control-Allow-Origin 就能够开启 CORS。 该属性表示哪些域名能够访问资源,若是设置通配符则表示全部网站均可以访问资源。

3、nginx 代理跨域

利用 Nginx 反向代理实现跨域。

虚拟主机的配置

server {
    listen 8080;                         # 监听的端口
    server_name  192.168.1.1;            # 配置访问域名
    root  /data/toor;                    # 站点根目录
    error_page 502 404 /page/404.html;   # 错误页面
    location ^~ /api/  {                        # 使用 /api/ 代理 proxy_pass 的值
        proxy_pass http://192.168.20.1:8080;    # 被代理的应用服务器 HTTP 地址
    }
}
复制代码

复制代码以上简单的配置就能够实现反向代理的功能,跨域的问题也就解决了。

在 Vue 中就可使用 proxyTable 这个属性进行相关的配置来解决跨域问题带来的烦恼。配置以下:

proxyTable: {
    '/weixin': {
        target: 'http://192.168.48.11:8100/', // 接口的域名 
        secure: false,      // 若是是 https 接口,须要配置这个参数
        changeOrigin: true, // 若是接口跨域,须要进行这个参数配置
        pathRewrite: {
            '^/weixin': ''
        }
    },
},
复制代码

正向代理和反向代理 TOP

正向代理

  1. 代理客户;
  2. 隐藏真实的客户,为客户端收发请求,使真实客户端对服务器不可见;
  3. 一个局域网内的全部用户可能被一台服务器作了正向代理,由该台服务器负责 HTTP 请求;
  4. 意味着同服务器作通讯的是正向代理服务器;

反向代理

  1. 代理服务器;
  2. 隐藏了真实的服务器,为服务器收发请求,使真实服务器对客户端不可见;
  3. 负载均衡服务器,将用户的请求分发到空闲的服务器上;
  4. 意味着用户和负载均衡服务器直接通讯,即用户解析服务器域名时获得的是负载均衡服务器的 IP ;

共同点

  1. 都是作为服务器和客户端的中间层
  2. 均可以增强内网的安全性,阻止 web 攻击
  3. 均可以作缓存机制

具体的应用能够看我写的这一篇文章 【前端词典】和媳妇讲代理后的意外收获

CDN 带来的性能优化 TOP

CDN的全称是 Content Delivery Network,即内容分发网络。CDN 是构建在网络之上的内容分发网络,依靠部署在各地的边缘服务器,经过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,下降网络拥塞,提升用户访问响应速度和命中率。CDN 的关键技术主要有内容存储和分发技术。

举个例子

在淘宝购物
咱们在淘宝购物,大部分我的卖家只是在一个地方发货,江浙沪之外的地方好像收货都比较慢。

在京东购物
而咱们在京东上买自营产品的话,它会根据咱们的收货地点,在全国范围内找离咱们最近、送达最快的仓库,无论咱们在江浙沪,仍是新疆西藏内蒙古,咱们的收货时间都会大大减小。京东创建的仓储系统,就相似于 CDN。

CDN的优点

  1. CDN 节点解决了跨运营商和跨地域访问的问题,访问延时大大下降;
  2. 大部分请求在 CDN 边缘节点完成,CDN 起到了分流做用,减轻了源站的负载。

访问速度快是电商网站取胜的必要法宝之一。

CDN 的工做模式

好比咱们 SHEIN 主站的根服务器中国深圳,CDN 服务器在美国加州,欧洲法国,印度等三个地方(真实的细致不少)。

没有 CDN 服务器

那么全球 6000 万用户请求的资源都是从中国深圳的机房发出的,这样一位美国加州的用户在打开首页的延时可能足够她画一个精致的妆容了。(PS: 深圳前端团队在招前端开发,有需求的能够私信我)

有 CDN 服务器

此时仍是这位加州的用户想打开 SHEIN 打算购买一件晚礼服参加晚会。此次她视线尚未移到梳妆台,首页就已经打开了,而后她就开心的购物了。

这就是由于 CDN 服务器。

美国加州的 CDN 服务器,已经将根节点的资源复制过来了。而且咱们有个机制,CDN 节点的资源十分钟会回源更新一次。因此在用户请求资源的时候是不会回源到深圳的根服务器请求的。这样不会出现用户在请求资源的时候,由于回源而致使的网络延时。

CDN 的核心点有两个: 一个是缓存,一个是回源。

关键技术

  1. 内容发布:它借助于创建索引、缓存、流分裂、组播(Multicast)等技术,将内容发布或投递到距离用户最近的远程服务点(POP)处;
  2. 内容路由:它是总体性的网络负载均衡技术,经过内容路由器中的重定向(DNS)机制,在多个远程 POP 上均衡用户的请求,以使用户请求获得最近内容源的响应;
  3. 内容交换:它根据内容的可用性、服务器的可用性以及用户的背景,在POP的缓存服务器上,利用应用层交换、流分裂、重定向(ICP、WCCP)等技术,智能地平衡负载流量;
  4. 性能管理:它经过内部和外部监控系统,获取网络部件的情况信息,测量内容发布的端到端性能(如包丢失、延时、平均带宽、启动时间、帧速率等),保证网络处于最佳的运行状态。

前端每每认为 CDN 是不须要了解的知识。但是咱们前端工程首先是软件工程师。多了解一些东西确定是有益的。

CDN & 静态资源

静态资源自己具备访问频率高、承接流量大的特色,所以静态资源加载速度始终是前端性能的一个很是关键的指标。CDN 是静态资源提速的重要手段。

淘宝

京东

掘金

咱们随手打开一个网站点开一个静态资源,能够看到它都是从 CDN 服务器上请求来的。能够看出 "静态资源走 CDN" 是最佳实践。

CDN & Cookie

Cookie 是紧跟域名的。同一个域名下的全部请求,都会携带相同的 Cookie。

可是若是咱们只是请求一张图片,咱们在请求中还要携带一个笨重的 Cookie 来回的跑,Cookie 中的信息和图片又是没有关联的,这种状况就很让人头痛了。Cookie 虽然小,可是随着请求的愈来愈多,这种的没必要要的 Cookie 带来的开销将是没法想象的……

静态资源每每并不须要 Cookie 携带什么认证信息。把静态资源和主页面置于不一样的域名下,就能够完美地避免请求中携带没必要要的 Cookie。

看起来是一个不起眼的小细节,但带来的效用倒是惊人的。电商网站静态资源的流量之庞大,若是没把这个多余的 Cookie 拿下来,不只用户体验会大打折扣,每一年因性能浪费致使的开销也会很是之高。

HTTP 强缓存&协商缓存 TOP

缓存是一种保存资源副本并在下次请求时直接使用该副本的技术。 当 web 缓存发现请求的资源已经被存储,它会拦截请求,返回该资源的拷贝,而不会去源服务器从新下载。
这样带来的好处是缓解服务器端压力,提高性能(获取资源的耗时更短了)。对于网站来讲,缓存是达到高性能的重要组成部分。
缓存大体可归为两类:私有缓存与共享缓存
共享缓存可以被多个用户使用;
私有缓存只能用于单独用户;

HTTP 协议主要是经过请求头当中的一些字段来和服务器进行通讯,从而采用不一样的缓存策略。
HTTP 经过缓存将服务器资源的副本保留一段时间,这段时间称为新鲜度限值。这在一段时间内请求相同资源不会再经过服务器。
HTTP 协议中 Cache-ControlExpires 能够用来设置新鲜度的限值。

强缓存 ( Cache-Control 和 Expires )

强缓存主要是采用响应头中的 Cache-ControlExpires 两个字段进行控制的。

其中 ExpiresHTTP 1.0 中定义的,它指定了一个绝对的过时时期。而 Cache-ControlHTTP 1.1 时出现的缓存控制字段。

Cache-Control:max-age 定义了一个最大使用期。 就是从第一次生成文档到缓存再也不生效的合法生存日期。因为Expires是HTTP1.0时代的产物,所以设计之初就存在着一些缺陷,若是本地时间和服务器时间相差太大,就会致使缓存错乱。

这两个字段同时使用的时候 Cache-Control 的优先级会更高一点。

这两个字段的效果是相似的,客户端都会经过对比本地时间和服务器返回的生存时间来检测缓存是否可用。若是缓存没有超出它的生存时间,客户端就会直接采用本地的缓存。若是生存日期已通过了,这个缓存也就宣告失效。接着客户端将再次与服务器进行通讯来验证这个缓存是否须要更新

Cache-Control 通用消息头字段被用于在 http 请求和响应中经过指定指令来实现缓存机制。

在请求头中使用 Cache-Control 时,它可选的值有:

指令 说明
no-cache 使用代理服务器的缓存以前提交原始服务器验证,验证经过才能使用
no-store 在客户端或是代理服务器都不缓存请求或响应的任何内容
max-age=[秒] 告知服务器客户端可接受资源的存在最大时间
max-stale(=[秒]) 可接受(代理服务器缓存的)过时资源,参数可省略
min-fresh=[秒] 可接受(代理服务器缓存的)资源更新时间小于指定时间
no-transform 代理服务器不能够更改媒体类型
only-if-cached 客户端只接受已缓存的响应,若缓存不命中,则返回 504 错误
cache-extension 自定义扩展值,若服务器不知别该指令,就直接忽略

在响应头中使用 Cache-Control 时,它可选的值有:

指令 说明
public 代表该资源能够给多个用户使用
private(= name) 该资源是私有资源,指定的用户可使用的缓存
no-cache 强制每次请求直接发送给源服务器,而不通过本地缓存版本的校验。
no-store 在客户端或是代理服务器都不缓存请求或响应的任何内容
no-transform 代理服务器不能够更改媒体类型
must-revalidate 可缓存但必须再向源服务器进行请求确认
proxy-revalidate 要求缓存服务器返回缓存的时候向源服务器进行请求确认
max-age=[秒] 告知客户端该资源在规定时间内是新鲜的,无需向服务器确认
s-maxage=[秒] 告知缓存服务该资源在规定时间内是新鲜的,无需向服务器确认
cache-extension 自定义扩展值,若服务器不识别该指令,就直接忽略

可缓存性

  1. public:响应能够被任何对象(客户端、代理服务器等)缓存
  2. private:只能被单个用户缓存,不能做为共享缓存
  3. no-cache:使用缓存副本以前,须要将请求提交给原始服务器进行验证,验证经过才可使用
  4. only-if-cached:客户端只接受已缓存的响应,而且不向原始服务器检查是否有更新的拷贝

到期

  1. max-age=<seconds>:缓存存储的最大周期,超过这个时间缓存被认为过时(单位秒)。与 Expires 相反,时间是相对于请求的时间
  2. s-maxage=<seconds>:覆盖 max-age 或者 Expires 头,可是仅适用于共享缓存(好比各个代理),而且私有缓存中它被忽略
  3. max-stale[=<seconds>]:代表客户端愿意接收一个已通过期的资源。可选的设置一个时间(单位秒),表示响应不能超过的过期时间
  4. min-fresh=<seconds>:表示客户端但愿在指定的时间内获取最新的响应

从新验证和从新加载

  1. must-revalidate:缓存必须在使用以前验证旧资源的状态,而且不可以使用过时资源。
  2. proxy-revalidate:与 must-revalidate 做用相同,但它仅适用于共享缓存(例如代理),并被私有缓存忽略

其余

  1. no-store:完全得禁用缓冲,本地和代理服务器都不缓冲,每次都从服务器获取
  2. no-transform:不得对资源进行转换或转变。Content-Encoding, Content-Range, Content-TypeHTTP 头不能由代理修改。

协商缓存 ( Last-Modified 和 Etag )

协商缓存机制下,浏览器须要向服务器去询问缓存的相关信息,进而判断是从新发起请求、下载完整的响应,仍是从本地获取缓存的资源。
若是服务端提示缓存资源未改动(Not Modified),资源会被重定向到浏览器缓存,这种状况下网络请求对应的状态码是 304

Last-Modified 和 If-Modified-Since

基于资源在服务器修改时间的验证缓存过时机制

当客户端再次请求该资源的时候,会在其请求头上附带上 If-Modified-Since 字段,值就是第一次获取请求资源时响应头中返回的 Last-Modified 值。若是资源未过时,命中缓存,服务器就直接返回 304 状态码,客户端直接使用本地的资源。不然,服务器从新发送响应资源。从而保证资源的有效性。

Etag 和 If-None-Match

基于服务资源校验码的验证缓存过时机制

服务器返回的报文响应头的 Etag 字段标示服务器资源的校验码(例如文件的 hash 值),发送到客户端浏览器,浏览器收到后把资源文件缓存起来而且缓存 Etag 值,当浏览器再次请求此资源文件时,会在请求头 If-None-Match 字段带上缓存的 Etag 值。
服务器收到请求后,把请求头中 If-None-Match 字段值与服务器端资源文件的验证码进行对比,若是匹配成功直接返回 304 状态码,从浏览器本地缓存取资源文件。若是不匹配,服务器会把新的验证码放在请求头的 Etag 字段中,而且以 200 状态码返回资源。

须要注意的是当响应头中同时存在 Etag 和 Last-Modified 的时候,会先对 Etag 进行比对,随后才是 Last-Modified

Etag 的问题
相同的资源,在两台服务器产生的 Etag 是否是相同的,因此对于使用服务器集群来处理请求的网站来讲,Etag 的匹配几率会大幅下降。所在在这种状况下,使用 Etag 来处理缓存,反而会有更大的开销。

参考

  1. 《图解 HTTP》
  2. 《计算机网络基础》
  3. blog.csdn.net/qzcsu/artic…
  4. segmentfault.com/a/119000001…
  5. developer.mozilla.org/zh-CN/docs/…

前端词典系列

《前端词典》这个系列会持续更新,每一期我都会讲一个出现频率较高的知识点。但愿你们在阅读的过程中能够斧正文中出现不严谨或是错误的地方,本人将不胜感激;若经过本系列而有所得,本人亦将不胜欣喜。

若是你以为个人文章写的还不错,能够关注个人微信公众号,公众号里会提早剧透呦。

你也能够添加个人微信 wqhhsd, 欢迎交流。

下期预告

【前端词典】F5 同 Ctrl+F5 的区别你可了解

传送门

  1. 【前端词典】和媳妇讲代理后的意外收获
  2. 【前端词典】滚动穿透问题的解决方案
  3. 继承(一) - 原型链你真的懂吗?
  4. 【前端词典】继承(二) - 回的八种写法·面试必问
  5. 【前端词典】进阶必备的网络基础(上)