经过讲故事搞定前端网络知识

本文约6000余字,阅读须要10分钟左右。前端

写在最前

有人说,前端工程师的网络基础很弱,说不少都是非计算机的,门槛低,其实不能一律而论。可是既然人家吐槽了,那咱们就提升本身呗。git

没有规矩,不成方圆

前端工程师对这句话应该有比较深入的感觉吧,这也多是前端变化真的太 TM 的快了。但变化的这么快,老是要沉淀下来一些 规矩 吧,否则的话还能不能过了。程序员

那沉淀下来的规矩在哪呢?github

规矩有不少,好比:AMDCMDPromise 等,均可以看作是一种 规矩 ,下文统一叫标准吧。web

有句话是这样说的:面试

能够随便造库,可是不要随便定标准。ajax

也就是说,若是没有足够多的人达成共识的话,那么你造的标准其实并无什么卵用。npm

因此,静下来想一下,咱们从哲学的角度看:编程

若是没有标准,那么这个世界将会变的很是无序和混乱,正由于有了标准,世界才变的有序整齐。设计模式

对此咱们能够类比数据概括法进行推导一下:

咱们将世界的网络( Internet ——国际互联网),进行概括,得出一个结论,若是世界上的网络没有约定标准的话,那也将会变的异常混乱。

因此,咱们学习网络基础,其实就是在学习当今 Internet 的标准。当咱们学会了标准后,咱们就能够遵循它,而后去作一些咱们想实现的东西。其实,你会发现,不少东西,都是这个道理。

now,咱们应该就知道要怎么去提升咱们的网络基础了。

咱们要去学习 Internet 的标准,看看它的标准是什么,为何要这样去设计标准,以及这样写的好处是什么,还有这样设计的编程思想是什么。

编程思想有时候会给咱们带来不少不同的感觉。

为何如今有 MVPMVVMMVX 等设计模式。那是由于优秀的程序员,去学习 MVC 的经典设计思想后,获得灵感,而后将一个经典设计思想,扩展出不少更加优秀的设计思想。因此,这也是咱们去学习一个东西的目的,也是一个可以使咱们造成一种自我驱动的一种学习模式。只有这样,咱们才能不断进步吧。


好了,不胡扯了,那下面我就开始以我我的的学习和看法,去阐述一下 网络基础

PS:PromisePromiseA/B/C/ 等等社区标准,可是最终选择了 PromiseA+ 做为官方标准。

Internet 并不神秘

Internet 真的并不神秘,且听我说:

想上网,首先你得有网络设备吧,这里不必定是要你去买,多是别人给你提供好了,好比运营商拉线子过来了,你就不用买线子了丫(手动滑稽),还有主机、交换机、路由器等,这些基本组成了 Internet 的网络设备。

可能一些人不理解每一个设备的做用,可是有一些东西,当你不了解的时候,就尝试使用 代入法 去理解。好比,可能对交换机和路由器不了解,可是不去了解,又会对后面的了解形成障碍,那么怎么办呢?

咱们能够把硬件设备当成软件看待

毕竟硬件里面也是有编的代码丫,固然有些没有代码,好比线子,集线器,可是咱们能够认为里面写了个空函数啊,那这样就能够从软件层面理解硬件了。

那再可爱一点:

咱们能够把完成特定功能的硬件当作是软件中的功能模块,有入参,有出参。

再形象点,能够理解成中间件

数据就是在一个个中间件中进行传输,而且在每一个中间件中作相应的处理,好比封装,验证正确性,最后数据展现在了你的眼睛里。

若是这样去理解,是否是感受没有想象中的深奥难懂了呢。

其实咱们的目的就是:

把抽象深奥的知识形象化,而后把形象化的知识抽象成咱们能理解的样子。

这样咱们就好像让咱们可爱的脑子完成了一次 babel 转译,真是有趣,这是一个快速理解深奥知识的一个技巧。知识不能学死了,万变不离其宗,不少地方都是同样的思想,学会融会贯通是一种很重要的能力。

一道经典题引起的联想

你能说说三次握手,四次挥手的过程吗?

相信不少人都会被问到过,这是在考察网络知识的状况下,基本少不掉的问题,也说明了这个问题所体现的知识是基础的,是在考察你的网络基础。

如今当咱们再次看到这个问题,咱们能够尝试向上溯源一下。好比,想一下为何要有这个过程,为何要这样去作,我两次握手解决不行吗,我不作第四次挥手不能够吗?

这里有一篇我的认为还不错的文章:

跟着动画学习TCP三次握手和四次挥手

关于三次握手和四次挥手的回答我就不回答了,上面文章已经介绍了比较清楚了。有啥疑问,能够文末扫我微信二维码,咱们私聊交流一波( 滑稽脸 )。

数据和电的故事

这是我胡诌的一个故事:

将数据从一个主机 [北京] 传输到另外一个主机 [南京] 是一个复杂的过程,不像是输电那样,一股脑输过来就行了,固然输电也是一门高学问,好比高压输电。

可是数据这东西比起电,可复杂多了。

好比,电是中央空调,谁掏钱,我就流向谁,你们都同样,没有什么。基本不会存在像:你这家电好可爱哦,你家的电比我家的电帅多了的这些状况😂。经过这个小栗子,我主要想说明电没有隐私,不具备让用户损失什么东西的可能。今晚电压低了,忍一忍,明天换个大的变压器,晚上就正常了,用户也不会说什么。

相比之下,数据可不同了,数据是一种具备隐私性质的信息,既然具备隐私,那就得保证安全性和完整性,并且不能时而安全,时而不安全,时而完整,时而不完整,因此一下就大大提升了传输的复杂程度。

一张图引起的联想

下面咱们看一张图:

image

首先这张图展现了目前整个 Internet 的层级结构。我如今也不解释为何是这样的,由于这是标准,已达成共识。可是我想说几个状况。

第一个状况:你确定不止一次看到过这种图,可是不少人仍是会在面试的时候被问倒,一时想不起来,这种状况的缘由,基本是当初没有理解,或者没有进行形象化的记忆。好比一个血淋淋的事实,就是英语单词背了那么多,仍是很快就忘。那么如今,咱们再看到这个图时,怎么保证下一次再也不被问倒了呢?

那就要从记忆学上作文章了,要联想,要有故事参与进来,带剧情的那种。OK ,那如今,咱们从这张图能联想到什么?这是一个问题,那么跟着我开始联想吧。

第一个角度

从前端角度来联想,OSI 七层模型到 TCP/IP 四层模型的转换过程当中,很明显是作了封装了。

从中间件的角度来思考,这 7 层或者 4 层,咱们均可以把每一层看作是中间件。数据在中间件之间进行流动,那么每一次通过一个中间件,也就意味着会进行一次数据处理。每一个中间件完成一个特定的功能。 TCP/IP 的四层是将七层的模型包装了一下,化繁为简的哲学。将功能重复性的层合并在同一层,有利于确保每一层的功能相对独立,属于更高级别的抽象。隐藏了细节,同时层级之间的功能区别更加明显。

第二个角度

能够从 npm 包的角度来思考,你会发如今 TCP/IP 分层结构中,高层级会依赖低层级。就好像是 npm 包,安装 A 包,你会自动安装 B 包,B 包又会依赖 C 包。也就是,要想安装成功 A 包,那么 B 包, C 包都要参与。OK,那这样理解的话,我应用层发起的数据流动,必定会依赖传输层,网络层,接口层。因此一些前端工程师只知道发起 ajax 或者 fetch 请求的时候,走了下 http 。对于走不走 tcp , ip ,接口层。不太清楚。因此,看到这里,我以为小伙伴仍是要好好理解一下你发起的数据请求是如何在网络中进行流动的。

HTTP/TCP/IP 三者的联系

三者有什么联系,这里我举个栗子,虽然不能算准确,但足够形象。

IP 是以主机为单位,经过 IP 能找到你所在的城市。

TCP 是以主机的端口为单位,经过 TCP 能找到你所在城市的你居住的小区。

HTTP 呢,它是以用户进程为单位,经过 HTTP 能找到你所在城市所在小区的房间号。

经过上面的比喻,是否是发现很是通俗易懂,这就是讲故事的魅力,哈哈哈。这个例子也能说明,若是你想找到房间号,那你确定是要先找到城市,而后再找到小区,最后找到房间号。也就是说你想发送 HTTP 成功的话,那必须是 TCP , IP 都要成功,你才能发送 HTTP 成功。

2019年2月3号备注:上面这个 HTTP/TCP/IP 三者的联系 的例子举的很不许确,在此表示道歉。

已有大佬和我进行了交流:

上图已经给出了正确的解释,主要缘由是我强行故事了一波,致使有点本末倒置,并且还容易误导小伙伴,道歉道歉😂。

IP

IP 层是网络层,定义了不一样主机之间的寻址方式。简单点理解,就是经过 IP 地址来找到对应的主机。

TCP/UDP

传输层是很是重要的一层,具备承上启下,向上对应用层提供通讯服务,向下将应用层信息封装为网络信息。

传输层链接主机之间的进程,同一主机中不一样进程的网络通讯经过端口进行区分,因此传输层为主机提供的是端口对端口的服务。

这里提一下,进程是什么

能够这样理解,当应用程序被调入内存运行后,这个应用程序就能够被称为进程了。

端口不属于任何应用程序

应用程序经过系统调用与某个端口创建链接( Binding )后,才会肯定这个端口是为这个进程服务的,数据什么的都是经过端口来传输给进程的。由于端口不属于任何应用程序,只是在绑定的时候,才会肯定为哪一个进程服务。

传输层和端口的交互方式

传输层传给该端口的数据都被相应的进程所接收,相应的进程发给传输层的数据都从该端口发出。这里的端口是传输层的寻址方式。

端口是软件级的概念

端口是由 16 位二进制数来表示的正整数,也就意味着一个主机理论上最多有 65535 个传输层信道。可是一般都少于 65535 个。 好比说,80 端口,21 端口,8080 端口等,都是默认的端口号,经过这些端口号来完成特定的通讯。

HTTP

HTTP 是构建在 TCP/IP 之上的应用层协议,而 HTTPS 是在 HTTP 之下加入 SSL/TLS

简单介绍下,HTTP 是超文本传输协议的英文缩写,它是 Internet 上最主要的 Web 应用层标准,HTTP 可以传输任何格式的数据。

做为前端工程师,咱们应该从 HTTP 里学习到什么呢?

咱们说一个事情,好比面试常常问你,输入一个 url 后,会发生什么,其实若是你理解的比较深的话,彻底能够画个图告诉他,固然打电话就只能口述了。

  1. 首先你点击一个 url ,是发起了一次 http 请求
  2. http 请求必定会依赖 tcpip 等。也就是意味着你要作 tcp 建连,IP 查询。
  3. 若是你的 url 是域名的话,还须要先去解析域名,也就是 dns 操做。使其变成 ip 地址。这个过程必定是在应用层完成的,由于应用层不完成的话,那 TCP 层就拿不到 IP 地址,那 IP 也就收不到地址数据。因此咱们这样一推导,也就这知道了 dns 是在应用层完成的。
  4. 数据正常传到接口层后,确定是要传到对应 IP 地址的服务器的对应端口。也就是 TCP 建联。TCP 要先建连成功,HTTP 才能进行传输。由于是依赖关系,接收方的 HTTP 须要从 TCP 那获取数据。若是 TCP 建连失败,那 HTTP 也就不可能建联成功。
  5. 若是都成功了,那就传输数据吧。
  6. 传输完,TCP 链接关闭。页面有了新的数据展现在用户的面前

看到这,你确定会想,缓存呢,这里我没有把缓存考虑进去,今晚缓存无处不在,缓存这个点你们自行填充吧。

下面能够用一张很酷的图,展现当输入 URL 时,整个过程是什么样子的。以下图所示:

HTTP 是一种标准,他有本身的形式,你看看 HTTP 的数据传输形式,你大概就能想象到 TCP 大概是什么样子的数据传输形式了。

网络请求的数据结构是前端控制的,好比请求的方法,请求的 url ,请求的参数等。那么响应的数据结构就应该是由服务端来控制了,服务端给咱们必要的返回信息,好比状态码,数据,缓存控制等。

HTTP状态码

web 编程中,状态码是很是重要的事情。

设置状态码的目的是什么?

是为了让开发人员和用户知道服务器是正常处理了请求仍是出现了错误。了解目的,对于咱们去了解状态码为何会这样分,是很是必要的事情,至少内心不那么感受到陌生了。

而在状态码中,有一个系列很是重要,那就是 3XX 系列。

301302 的区别

302 临时重定向

临时重定向,意识是当服务端关闭的时候,客户端发起 url 请求,是不能成功的。它还须要向服务端发起请求,让服务端重定向到目标网址,也就是返回 location ,而后再转到目标网址。

PS: 思考一下,为何会有 302 ?

301 永久重定向

永久重定向,是即便服务端关闭了,浏览器端发起 url 请求,也能够不通过服务端而直接转到目标网址。除非清理缓存,不然之后再次访问都是直接访问另外一个地址。

HTTP 请求方法

能够这样理解,HTTP 就比如一个对象参数,里面有 Method ,表明 HTTP 的请求方法,用来告诉服务器,客户端访问你的 url 的目的是什么,是获取信息,上传数据仍是删除信息。一般用到的最多就是 GETPOST 。常常用的 GETPOST 就不说了,这里说一下 OPTIONS

OPTIONS 是为客户端提供一种查询 URL 地址中有哪些可用的访问方式的方法。

PS: 留给思考,这个 OPTIONS 的使用场景是什么呢?

POSTPUT 的区别:

POSTPOST的数据,服务器必须保证数据被完整的保存,而且不容许出现重复的 POST 数据提交。一般在 HTML 中经过表单来提交数据。

PUTPUT 容许客户端提交重复的数据,当提交重复的数据时,会用新提交的数据覆盖掉服务器已有的数据。

PS: 这里推荐一本我读过的书籍 《图解HTTP》写的很不错,图文并茂,简单易懂,值得阅读。

HTTP是怎么在服务端走的

看下面我画的一张图,这是服务器端程序、Web 服务器、客户端之间的关系:

上图是主流的模式,Web 服务器仅起到桥梁的做用,即将浏览器的 HTTP 请求解码,转换成服务器端程序可以识别的接口调用方式,而后服务器端程序会将生成的返回封装成 HTTP Response ,并返回给用户。

注意1:

在服务端,用户发的请求,若是是为了获取静态资源的话,通常是不通过服务器端程序的,直接经过服务端的缓存机制,返回资源给用户,好比 Nginx 的静态资源缓存。不走服务端程序,会大大提升响应速度。

注意2:

服务端通常都是在公司的内网,外网是没法访问的,发起 HTTP 请求,其实大多数状况下都是先经过 Nginx 进行反向代理,同时也是负责流量转发,将不一样的请求转发给内网特定的服务器。

Socket

Socket 在汉语中是指孔或插座的意识,顾名思义,插上了就能够通讯了。Socket 一开始是做为 BSD UNIX 的进程通讯机制,而后逐渐成为主流操做系统共同遵照的网络编程标准。

Socket 是什么

Socket 是一个通讯链的句柄,能够用来实现不一样虚拟机或不一样计算机之间的通讯,也能够实现相同主机内的不一样进程之间的通信。

Socket 的组成

Socket = IP 地址 + 端口 + 协议

IP 地址 + 端口 + 协议 组成一个惟一标识,用来标识一个通讯链路。

能够看到,Socket 实际上是对 TCP/IP 进行了高度封装,屏蔽了不少网络细节。这样可使开发者更好地进行网络编程。其实就是咱们写个高度封装内部细节的函数,经过传参来完成指定的行为。

能够这么说,全部的 TCP/UDP 等编程,基本都是按照 Socket 协议标准来进行编程的,换句话说,Socket 是一套标准,就比如 DOM ,全部语言均可以按照 DOM 的接口标准来实现本身的逻辑。

Socket 有本身的原语,开发者能够按照 Socket 的原语在不一样语言下的实现方式来进行网络编程。

谈谈 WebSocket

WebSocket 是什么?

这是 HTML5 定义的一种新的标准协议,实现了浏览器与服务器的全双工通讯。咱们能够将 WebSocket 理解为 Web + Socket ,它是一种双工通讯。

什么是双工通讯?

就是在同一时刻,我既能够扮演通讯双方的发送方,也能够扮演通讯双方的接收方。

为何会出现 WebSocket

WebSocket 出来以前,前端的 Web 通讯基本就靠 HTTP ,可是 HTTP ( 1 或者 2 ) 请求自己有一些缺陷,好比:

  1. 首部信息冗余,每次发送请求,都要携带大量冗余信息。
  2. 不能实现双工通讯。

因此在这个技术背景下,WebSocket 技术出现了,弥补了 HTTP 的缺陷。可是咱们又不能不用 HTTP ,由于已经用的场景太多了,因此就综合了一下,让 WebSocket 协议是在 HTTP 协议之上的。这样就能够作到平稳过渡到新的通讯协议上了。

WebSocket 的通讯原理

WebSocket 是创建在 HTTP 之上的,也就意味着你要创建 WebSocket 的话,须要走一次 HTTP ,走完后,你的 WebSocket 就创建起长链接了。而后只要不是主动断开的,就会保持好客户端和服务端之间的链接,不会使其断开。当有数据传输的时候,会直接进行传输,再也不发起 HTTP 请求。

前端使用 WebSocket 很简单,就那么几个 API ,可自行去查看。可是咱们要清楚每一个 API 究竟发生了什么事情,只有理解了背后的那些真相,咱们才算是真正理解了 WebSocket

WebSocket 优势

  1. 支持推送功能,服务端能够向客户端推送数据。
  2. 减小通讯量,一方面是 WebSocket 的首部信息很小,另外一方面是不须要频繁进行 HTTP 链接了,能够进行持久链接。

这里推荐一篇文章,写的挺不错,能够看看:

WebSocket 是什么原理?为何能够实现持久链接?

C/S 和 B/S 架构

对于前端工程师来讲,仍是要去了解一下 web 架构的发展演变的,提到发展演变,不得不说一下 C/SB/S 架构。

C/S

C/S ,即 Client/Server ,当前网络编程的主流架构模型。 Clent 是客户端的意识,S 是 服务端的意识。

B/S

Browser/Server ,是使用 Web 浏览器做为客户端的应用软件。

从上面介绍咱们能够推断出,C/S 中的 C 有不少,好比 APP ,桌面应用等。可是 B/S 中的 B 只特指浏览器。

问题来了,B/S 结构与 C/S 结构相比,有什么区别或者说有什么优点呢?

B/S 的优缺点

优势

第一: 最显而易见的就是,B/S 部署升级快,无需应用程序更新,由于 B/S 系统的全部应用程序都是部署在服务器上的,不须要更新客户端软件。因此不少 APP 内都内嵌 H5Hybrid 。 由于不须要审核,能够直接发布。为何不须要审核呢,是由于前端的跨域限制,JS 是没法获取设备其余信息的,不须要担忧安全问题,也就不用审核了。

第二: 跨平台,由于操做系统都支持 Web 浏览器,因此只须要在浏览器中运行就行了。

缺点

安全性要求高,B/S 架构是创建在广域网上的,面向全部用户。经过 url 就能够访问服务器端资源,因此安全性要求要比 C/S 要高。

备注

  1. 没有写过多细节,一些细节自行去理解吧,也能够私聊我技术交流。
  2. 本文在总体上阐述了一个前端工程师应该要去掌握的网络知识。
  3. 本文字数还行,看着应该不怎么累( 笑哭脸 )。

参考链接

关于TCP/IP,必须知道的十个知识点

文末总结

读到这,咱们会发现,网络知识没有那么神秘,认真去学习,你也能够搞定前端网络知识。

交流

掘金系列技术文章汇总以下,以为不错的话,点个 star 鼓励一下,也能够 github 关注我一波,持续输出精品文章。

github.com/godkun/blog

我是源码终结者,欢迎技术交流,欢迎关注个人掘金博客,不按期分享知识。

对了,还差了什么,固然是祝各位小伙伴猪年大吉吧!!

相关文章
相关标签/搜索