计算机网络相关知识

一、常见状态码

1. 消息

100 Continue客户端应当继续发送请求。这个临时响应是用来通知客户端它的部分请求已经被服务器接收,且仍未被拒绝。客户端应当继续发送请求的剩余部分,或者如果请求已经完成,忽略这个响应。服务器必须在请求完成后向客户端发送一个最终响应。

2. 成功

200 OK:请求已成功,请求所希望的响应头或数据体将随此响应返回。出现此状态码是表示正常状态。201 Created:请求已经被实现,而且有一个新的资源已经依据请求的需要而建立,且其 URI 已经随Location 头信息返回。假如需要的资源无法及时建立的话,应当返回 '202 Accepted'。
202 Accepted:服务器已接受请求,但尚未处理。正如它可能被拒绝一样,最终该请求可能会也可能不会被执行。在异步操作的场合下,没有比发送这个状态码更方便的做法了。

3. 重定向

301 Moved Permanently:被请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用本响应返回的若干个 URI 之一。如果可能,拥有链接编辑功能的客户端应当自动把请求的地址修改为从服务器反馈回来的地址。除非额外指定,否则这个响应也是可缓存的。
新的永久性的URI 应当在响应的 Location 域中返回。除非这是一个 HEAD 请求,否则响应的实体中应当包含指向新的 URI 的超链接及简短说明。
如果这不是一个 GET 或者 HEAD 请求,因此浏览器禁止自动进行重定向,除非得到用户的确认,因为请求的条件可能因此发生变化。
注意:对于某些使用 HTTP/1.0 协议的浏览器,当它们发送的 POST 请求得到了一个301响应的话,接下来的重定向请求将会变成 GET 方式。
302 Move Temporarily:请求的资源临时从不同的 URI响应请求。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。只有在Cache-Control或Expires中进行了指定的情况下,这个响应才是可缓存的。上文有提及。
如果这不是一个 GET 或者 HEAD 请求,那么浏览器禁止自动进行重定向,除非得到用户的确认,因为请求的条件可能因此发生变化。
注意:虽然RFC 1945和RFC 2068规范不允许客户端在重定向时改变请求的方法,但是很多现存的浏览器将302响应视作为303响应,并且使用 GET 方式访问在 Location 中规定的 URI,而无视原先请求的方法。状态码303和307被添加了进来,用以明确服务器期待客户端进行何种反应。
303 See Other:对应当前请求的响应可以在另一个 URL 上被找到,而且客户端应当采用 GET 的方式访问那个资源。这个方法的存在主要是为了允许由脚本激活的POST请求输出重定向到一个新的资源。这个新的 URI 不是原始资源的替代引用。同时,303响应禁止被缓存。当然,第二个请求(重定向)可能被缓存。
注意:许多 HTTP/1.1 版以前的浏览器不能正确理解303状态。如果需要考虑与这些浏览器之间的互动,302状态码应该可以胜任,因为大多数的浏览器处理302响应时的方式恰恰就是上述规范要求客户端处理303响应时应当做的。
304 Not Modified:如果客户端发送了一个带条件的 GET 请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个状态码。304响应禁止包含消息体,因此始终以消息头后的第一个空行结尾。
该响应必须包含以下的头信息:
Date,除非这个服务器没有时钟。假如没有时钟的服务器也遵守这些规则,那么代理服务器以及客户端可以自行将 Date 字段添加到接收到的响应头中去(正如RFC 2068中规定的一样),缓存机制将会正常工作。
ETag 和/或 Content-Location,假如同样的请求本应返回200响应。
Expires, Cache-Control,和/或Vary,假如其值可能与之前相同变量的其他响应对应的值不同的话。
假如本响应请求使用了强缓存验证,那么本次响应不应该包含其他实体头;否则(例如,某个带条件的 GET 请求使用了弱缓存验证),本次响应禁止包含其他实体头;这避免了缓存了的实体内容和更新了的实体头信息之间的不一致。
假如某个304响应指明了当前某个实体没有缓存,那么缓存系统必须忽视这个响应,并且重复发送不包含限制条件的请求。
假如接收到一个要求更新某个缓存条目的304响应,那么缓存系统必须更新整个条目以反映所有在响应中被更新的字段的值。

4. 请求错误

400 Bad Request:语义有误,当前请求无法被服务器理解。除非进行修改,否则客户端不应该重复提交这个请求。请求参数有误。

401 Unauthorized:当前请求需要用户验证。该响应必须包含一个适用于被请求资源的 WWW-Authenticate 信息头用以询问用户信息。客户端可以重复提交一个包含恰当的 Authorization 头信息的请求。如果当前请求已经包含了 Authorization 证书,那么401响应代表着服务器验证已经拒绝了那些证书。如果401响应包含了与前一个响应相同的身份验证询问,且浏览器已经至少尝试了一次验证,那么浏览器应当向用户展示响应中包含的实体信息,因为这个实体信息中可能包含了相关诊断信息。参见RFC 2617。

403 Forbidden:服务器已经理解请求,但是拒绝执行它。与401响应不同的是,身份验证并不能提供任何帮助,而且这个请求也不应该被重复提交。如果这不是一个 HEAD 请求,而且服务器希望能够讲清楚为何请求不能被执行,那么就应该在实体内描述拒绝的原因。当然服务器也可以返回一个404响应,假如它不希望让客户端获得任何信息。

404 Not Found:请求失败,请求所希望得到的资源未被在服务器上发现。没有信息能够告诉用户这个状况到底是暂时的还是永久的。假如服务器知道情况的话,应当使用410状态码来告知旧资源因为某些内部的配置机制问题,已经永久的不可用,而且没有任何可以跳转的地址。404这个状态码被广泛应用于当服务器不想揭示到底为何请求被拒绝或者没有其他适合的响应可用的情况下。出现这个错误的最有可能的原因是服务器端没有这个页面。

405 Method Not Allowed:请求行中指定的请求方法不能被用于请求相应的资源。该响应必须返回一个Allow 头信息用以表示出当前资源能够接受的请求方法的列表。

鉴于 PUT,DELETE 方法会对服务器上的资源进行写操作,因而绝大部分的网页服务器都不支持或者在默认配置下不允许上述请求方法,对于此类请求均会返回405错误。

406 Not Acceptable:请求的资源的内容特性无法满足请求头中的条件,因而无法生成响应实体。

5. 服务器错误

500 Internal Server Error:服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。一般来说,这个问题都会在服务器端的源代码出现错误时出现。

501 Not Implemented:服务器不支持当前请求所需要的某个功能。当服务器无法识别请求的方法,并且无法支持其对任何资源的请求。

502 Bad Gateway:作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应。

503 Service Unavailable:由于临时的服务器维护或者过载,服务器当前无法处理请求。这个状况是临时的,并且将在一段时间以后恢复。如果能够预计延迟时间,那么响应中可以包含一个 Retry-After 头用以标明这个延迟时间。如果没有给出这个 Retry-After 信息,那么客户端应当以处理500响应的方式处理它。

注意:503状态码的存在并不意味着服务器在过载的时候必须使用它。某些服务器只不过是希望拒绝客户端的连接。

504 Gateway Timeout:作为网关或者代理工作的服务器尝试执行请求时,未能及时从上游服务器(URI标识出的服务器,例如HTTP、FTP、LDAP)或者辅助服务器(例如DNS)收到响应。

注意:某些代理服务器在DNS查询超时时会返回400或者500错误

505 HTTP Version Not Supported:服务器不支持,或者拒绝支持在请求中使用的 HTTP 版本。这暗示着服务器不能或不愿使用与客户端相同的版本。响应中应当包含一个描述了为何版本不被支持以及服务器支持哪些协议的实体。

二、缓存

1. 浏览器缓存

· 200 OK (from cache) ——强制缓存,指的是浏览器没有跟服务器确认,直接用了浏览器缓存。通过设置 expires/cache-control 来实现的。虽然是强缓存,但用户主动触发的刷新行为,还是会采用缓存协商的策略,主动触发的刷新行为包括点击刷新按钮、右键刷新、f5刷新、ctrl+f5刷新等。
· 304 Not Modified——协商缓存,比 200 OK (from cache) 慢,指的是浏览器还向服务器确认了下 "If-Not-Modified",才用的缓存。

(1)Last-Modified:表示文档的最后修改时间,当去服务器验证时会拿这个时间去;
(2)Expires:http/1.0规范定义,表示文档在浏览器中的过期时间,当缓存的内容超过这个时间则需要重新去服务器获取最新的内容;
(3)Cache-Control:http/1.1规范定义,表示浏览器缓存控制,max-age=3153600表示文档可以在浏览器中缓存一年。

Last-Modified:在浏览器第一次请求某一个URL时,服务器端的返回状态会是200,资源响应头有一个Last-Modified的属性标记此文件在服务期端最后被修改的时间,另外一半也有个Etag。

HTTP中,通过Cache-Control首部和Expires首部为文档指定了过期时间,通过对过期时间的判断,缓存就可以知道文档是不是在保质期内。

Last-Modified(Etag)
(1)Last-Modified : http1.0时期属性, 现在仍在使用。
(2)ETag(Entity Tag) http1.1时期新加属性 。因为以下几个原因增加此属性:

  • 某些服务器不能精确得到文件的最后修改时间, 这样就无法通过最后修改时间来判断文件是否更新了。
  • 某些文件的修改非常频繁,在秒以下的时间内进行修改. Last-Modified只能精确到秒。
  • 一些文件的最后修改时间改变了,但是内容并未改变。 我们不希望客户端认为这个文件修改了。

Last-Modified与ETag同时使用时,浏览器在验证时会同时发送If-Modified-Since和If-None-Match,按照http/1.1规范,如果同时使用If-Modified-Since和If-None-Match则服务端必须两个都验证通过后才能返回304;且nginx就是这样做的。因此实际使用时应该根据实际情况选择。
分布式的Web系统中,当访问落在不同的物理机上时会返回不同的ETag,进而导致304失效,降级为200请求,所以经常在使用中会关闭ETag。

Cache-Control(expires)
(1)Pragma : no-cache http1.0时期的属性 为了兼容会使用
(2)expires:0 http1.0时期的属性 ,现在默认浏览器均默认使用HTTP 1.1,所以它的作用基本忽略。expires 的一个缺点就是,返回的到期时间是服务器端的时间,这样存在一个问题,如果客户端的时间与服务器的时间相差很大(比如时钟不同步,或者跨时区),那么误差就很大,所以在HTTP 1.1版开始,使用Cache-Control: max-age=秒替代。
(3)Cache-Control http1.1 中加入的新属性,它有以下常用参数:

  • Public/Private 私有缓存/共有缓存
  • no-cache:不建议使用本地缓存,但仍然会缓存到本地。虽然不使用本地缓存。需要使用缓存协商,先与服务器确认返回的响应是否被更改,如果之前的响应中存在ETag,那么请求的时候会与服务端验证,如果资源未被更改,则可以避免重新下载。
  • no-store:不会在客户端缓存任何数据
  • max-age:比较特殊,是一个混合属性,替代了Expires的过期时间

2. 301,302重定向

2.1 共同点和不同点

  • 301和302状态码都表示重定向,就是说浏览器在拿到服务器返回的这个状态码后会自动跳转到一个新的URL地址,这个地址可以从响应的Location首部中获取(用户看到的效果就是他输入的地址A瞬间变成了另一个地址B)

  • 301表示旧地址A的资源已经被永久地移除了(这个资源不可访问了),搜索引擎在抓取新内容的同时也将旧的网址交换为重定向之后的网址
  • 302表示旧地址A的资源还在(仍然可以访问),这个重定向只是临时地从旧地址A跳转到地址B,搜索引擎会抓取新的内容而保存旧的网址

2.2 应用场景

  • 场景一 想换个域名,旧的域名不用啦,这样用户访问旧域名时用301就重定向到新的域名。其实也是告诉搜索引擎收录的域名需要对新的域名进行收录。

  • 场景二 登录后重定向到指定的页面,这种场景比较常见就是登录成功跳转到具体的系统页面。

  • 场景三 有时候需要自动刷新页面,比如5秒后回到订单详细页面之类。

  • 场景四 有时系统进行升级或者切换某些功能时,需要临时更换地址。

  • 场景五 像微博之类的使用短域名,用户浏览后需要重定向到真实的地址之类。

2.3 301与302在选择上注意的问题——302 重定向和网址劫持(URL hijacking)

从网址A 做一个302 重定向到网址B 时,主机服务器的隐含意思是网址A 随时有可能改主意,重新显示本身的内容或转向其他的地方。大部分的搜索引擎在大部分情况下,当收到302重定向时,一般只要去抓取目标网址就可以了,也就是说网址B。如果搜索引擎在遇到302 转向时,百分之百的都抓取目标网址B 的话,就不用担心网址URL 劫持了。问题就在于,有的时候搜索引擎,尤其是Google,并不能总是抓取目标网址。比如说,有的时候A 网址很短,但是它做了一个302重定向到B网址,而B网址是一个很长的乱七八糟的URL网址,甚至还有可能包含一些问号之类的参数。很自然的,A网址更加用户友好,而B网址既难看,又不用户友好。这时Google很有可能会仍然显示网址A。由于搜索引擎排名算法只是程序而不是人,在遇到302重定向的时候,并不能像人一样的去准确判定哪一个网址更适当,这就造成了网址URL劫持的可能性。也就是说,一个不道德的人在他自己的网址A做一个302重定向到你的网址B,出于某种原因, Google搜索结果所显示的仍然是网址A,但是所用的网页内容却是你的网址B上的内容,这种情况就叫做网址URL 劫持。你辛辛苦苦所写的内容就这样被别人偷走了。302重定向所造成的网址URL劫持现象,已经存在一段时间了。不过到目前为止,似乎也没有什么更好的解决方法。

大体意思是会引起搜索引擎的排名,而且302重定向很容易被搜索引擎误认为是利用多个域名指向同一网站,那么你的网站就会被封掉。总之,除非真是临时重定向使用302,其他的情况最好还是使用301.

三、cookie, session, token

Cookie

cookie 是一个非常具体的东西,指的就是浏览器里面能永久存储的一种数据,仅仅是浏览器实现的一种数据存储功能。

cookie由服务器生成,发送给浏览器,浏览器把cookie以kv形式保存到某个目录下的文本文件内,下一次请求同一网站时会把该cookie发送给服务器。由于cookie是存在客户端上的,所以浏览器加入了一些限制确保cookie不会被恶意使用,同时不会占据太多磁盘空间,所以每个域的cookie数量是有限的。服务端可以设置httpOnly,使得前端无法操作cookie

Session

session 从字面上讲,就是会话。这个就类似于你和一个人交谈,你怎么知道当前和你交谈的是张三而不是李四呢?对方肯定有某种特征(长相等)表明他就是张三。

session 也是类似的道理,服务器要知道当前发请求给自己的是谁。为了做这种区分,服务器就要给每个客户端分配不同的“身份标识”,然后客户端每次向服务器发请求的时候,都带上这个“身份标识”,服务器就知道这个请求来自于谁了。至于客户端怎么保存这个“身份标识”,可以有很多种方式,对于浏览器客户端,大家都默认采用 cookie 的方式。

服务器使用session把用户的信息临时保存在了服务器上,用户离开网站后session会被销毁。这种用户信息存储方式相对cookie来说更安全,可是session有一个缺陷:如果web服务器做了负载均衡,那么下一个操作请求到了另一台服务器的时候session会丢失。

Token

在Web领域基于Token的身份验证随处可见。在大多数使用Web API的互联网公司中,tokens 是多用户下处理认证的最佳方式。

以下几点特性会让你在程序中使用基于Token的身份验证

1.无状态、可扩展

 2.支持移动设备

 3.跨程序调用

 4.安全

基于服务器验证方式暴露的一些问题

1.Seesion:每次认证用户发起请求时,服务器需要去创建一个记录来存储信息。当越来越多的用户发请求时,内存的开销也会不断增加。

2.可扩展性:在服务端的内存中使用Seesion存储登录信息,伴随而来的是可扩展性问题。

3.CORS(跨域资源共享):当我们需要让数据跨多台移动设备上使用时,跨域资源的共享会是一个让人头疼的问题。在使用Ajax抓取另一个域的资源,就可以会出现禁止请求的情况。

4.CSRF(跨站请求伪造):用户在访问银行网站时,他们很容易受到跨站请求伪造的攻击,并且能够被利用其访问其他的网站。

在这些问题中,可扩展行是最突出的。因此我们有必要去寻求一种更有行之有效的方法。

基于Token的验证原理

基于Token的身份验证是无状态的,我们不将用户信息存在服务器或Session中。这种概念解决了在服务端存储信息时的许多问题,NoSession意味着你的程序可以根据需要去增减机器,而不用去担心用户是否登录。

基于Token的身份验证的过程如下:

1.用户通过用户名和密码发送请求。

2.程序验证。

3.程序返回一个签名的token 给客户端。

4.客户端储存token,并且每次用于每次发送请求。

5.服务端验证token并返回数据。

本部分摘自:https://www.cnblogs.com/moyand/p/9047978.html

四、前端持久化的方式、区别

1.使用前端cookie技术来保存本地化数据,如jquery.cookie.js;

2.使用html5提供的localStorage技术来提供解决方案;

html5中的Web Storage包括了两种存储方式:sessionStorage和localStorage。
sessionStorage用于本地存储一个会话(session)中的数据,这些数据只有在同一个会话中的页面才能访问并且当会话结束后数据也随之销毁。因此sessionStorage不是一种持久化的本地存储,仅仅是会话级别的存储。而localStorage用于持久化的本地存储,除非主动删除数据,否则数据是永远不会过期的。如果是要永久保存的,那么就请使用localStorage方法存取值,如果是要浏览关闭会话结束就清除缓存的,当然就得选择sessionStorage方法了;

五、DNS是怎么解析的

网络通讯大部分是基于TCP/IP的,而TCP/IP是基于IP地址的,所以计算机在网络上进行通讯时只能识别如“202.96.134.133”之类的IP地址,而不能认识域名。我们无法记住10个以上IP地址的网站,所以我们访问网站时,更多的是在浏览器地址栏中输入域名,就能看到所需要的页面,这是因为有一个叫“DNS服务器”的计算机自动把我们的域名“翻译”成了相应的IP地址,然后调出IP地址所对应的网页。它所提供的服务是用来将主机名和域名转换为IP地址.

1、在浏览器中输入www . qq .com 域名,操作系统会先检查自己本地的hosts文件是否有这个网址映射关系,如果有,就先调用这个IP地址映射,完成域名解析。

2、如果hosts里没有这个域名的映射,则查找本地DNS解析器缓存,是否有这个网址映射关系,如果有,直接返回,完成域名解析。

3、如果hosts与本地DNS解析器缓存都没有相应的网址映射关系,首先会找TCP/ip参数中设置的首选DNS服务器,在此我们叫它本地DNS服务器,此服务器收到查询时,如果要查询的域名,包含在本地配置区域资源中,则返回解析结果给客户机,完成域名解析,此解析具有权威性。

4、如果要查询的域名,不由本地DNS服务器区域解析,但该服务器已缓存了此网址映射关系,则调用这个IP地址映射,完成域名解析,此解析不具有权威性。

5、如果本地DNS服务器本地区域文件与缓存解析都失效,则根据本地DNS服务器的设置(是否设置转发器)进行查询,如果未用转发模式,本地DNS就把请求发至13台根DNS,根DNS服务器收到请求后会判断这个域名(.com)是谁来授权管理,并会返回一个负责该顶级域名服务器的一个IP。本地DNS服务器收到IP信息后,将会联系负责.com域的这台服务器。这台负责.com域的服务器收到请求后,如果自己无法解析,它就会找一个管理.com域的下一级DNS服务器地址()给本地DNS服务器。当本地DNS服务器收到这个地址后,就会找域服务器,重复上面的动作,进行查询,直至找到www . qq .com主机。

6、如果用的是转发模式,此DNS服务器就会把请求转发至上一级DNS服务器,由上一级服务器进行解析,上一级服务器如果不能解析,或找根DNS或把转请求转至上上级,以此循环。不管是本地DNS服务器用是是转发,还是根提示,最后都是把结果返回给本地DNS服务器,由此DNS服务器再返回给客户机。 
从客户端到本地DNS服务器是属于递归查询,而DNS服务器之间就是的交互查询就是迭代查询。

1) 浏览器缓存

当用户通过浏览器访问某域名时,浏览器首先会在自己的缓存中查找是否有该域名对应的IP地址(若曾经访问过该域名且没有清空缓存便存在);

2) 系统缓存

当浏览器缓存中无域名对应IP则会自动检查用户计算机系统Hosts文件DNS缓存是否有该域名对应IP;

3) 路由器缓存

当浏览器及系统缓存中均无域名对应IP则进入路由器缓存中检查,以上三步均为客服端的DNS缓存;

4) ISP(互联网服务提供商)DNS缓存

当在用户客服端查找不到域名对应IP地址,则将进入ISP DNS缓存中进行查询。比如你用的是电信的网络,则会进入电信的DNS缓存服务器中进行查找;

5) 根域名服务器

当以上均未完成,则进入根服务器进行查询。全球仅有13台根域名服务器,1个主根域名服务器,其余12为辅根域名服务器。根域名收到请求后会查看区域文件记录,若无则将其管辖范围内顶级域名(如.com)服务器IP告诉本地DNS服务器;

6) 顶级域名服务器

顶级域名服务器收到请求后查看区域文件记录,若无则将其管辖范围内主域名服务器的IP地址告诉本地DNS服务器;

7) 主域名服务器

主域名服务器接受到请求后查询自己的缓存,如果没有则进入下一级域名服务器进行查找,并重复该步骤直至找到正确纪录;

8)保存结果至缓存

本地域名服务器把返回的结果保存到缓存,以备下一次使用,同时将该结果反馈给客户端,客户端通过这个IP地址与web服务器建立链接。

六、cdn

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

CDN的基本原理是广泛采用各种缓存服务器,将这些缓存服务器分布到用户访问相对集中的地区或网络中,在用户访问网站时,利用全局负载技术将用户的访问指向距离最近的工作正常的缓存服务器上,由缓存服务器直接响应用户请求。 
CDN的基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定。通过在网络各处放置节点服务器所构成的在现有的互联网基础之上的一层智能虚拟网络,CDN系统能够实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上。其目的是使用户可就近取得所需内容,解决 Internet网络拥挤的状况,提高用户访问网站的响应速度。
主要功能
(1)节省骨干网带宽,减少带宽需求量;
(2)提供服务器端加速,解决由于用户访问量大造成的服务器过载问题;
(3)服务商能使用Web Cache技术在本地缓存用户访问过的Web页面和对象,实现相同对象的访问无须占用主干的出口带宽,并提高用户访问因特网页面的相应时间的需求;
(4)能克服网站分布不均的问题,并且能降低网站自身建设和维护成本;
(5)降低“通信风暴”的影响,提高网络访问的稳定性。 

七、计算机网络的相关协议

协议数据单元PDU(Protocol Data Unit)是指对等层次之间传递的数据单位

物理层的 PDU是数据位(bit)

数据链路层的 PDU是数据帧(frame)

网络层的PDU是数据报(packet)

传输层的 PDU是数据段(segment)

其他更高层次的PDU是报文(message)

应用层: (典型设备:应用程序,如FTP,SMTP ,HTTP)

DHCP(Dynamic Host Configuration Protocol)动态主机分配协议,使用 UDP 协议工作,主要有两个用途:给内部网络或网络服务供应商自动分配 IP 地址,给用户或者内部网络管理员作为对所有计算机作中央管理的手段。实现即插即用连网。

DNS (Domain Name System )域名解析<端口号53>

FTP (File Transfer Protocol )文件传输协议<端口号21>减少或消除不同操作系统下处理文件的不兼容性。

HTTP (Hypertext Transfer Protocol )超文本传输协议 <端口号 80>, 面向事务的应用层协议。

POP3 (Post Office Protocol 3) 即邮局协议的第3 个版本,用于接受邮件。

SMTP (Simple Mail Transfer Protocol )简单邮件传输协议 <端口号25> 用于发送邮件。

SSH (Secure Shell )安全外壳协议

TELNET 远程登录协议 <端口号23>

传输层: (典型设备: 进程和端口) 数据单元:数据段 (Segment)

TCP (Transmission Control Protocol )传输控制协议提供可靠的面向连接的服务,传输数据前须先建立连接,结束后释放。可靠的全双工信道。可靠、有序、无丢失、不重复。

UDP (User Datagram Protocol )用户数据报协议发送数据前无需建立连接,不使用拥塞控制,不保证可靠交付,最大努力交付。

网络层: (典型设备:路由器,防火墙、多层交换机) 数据单元:数据包(Packet )

IP (IPv4 · IPv6) (Internet Protocol) 网络之间互连的协议

ARP (Address Resolution Protocol) 即地址解析协议,实现通过IP 地址得 知其物理地址。

RARP (Reverse Address Resolution Protocol)反向地址转换协议允许局域 网的物理机器从网关服务器的 ARP 表或者缓存上请求其 IP地址。

ICMP (Internet Control Message Protocol )Internet 控制报文协议。它是TCP/IP 协议族的一个子协议,用于在IP 主机、路由器之间传递控制消息。

ICMPv6 :
IGMP (Internet Group Management Protocol) Internet 组管理协议,是因特 网协议家族中的一个组播协议,用于 IP 主机向任一个直接相邻的路由器报 告他们的组成员情况。

RIP (Router information protocol) 路由信息协议是一种在网关与主机之间交换路由选择信息的标准。

OSPF (Open Shortest Path Firs)开放式最短路径优先,分布式链路状态协议。

BGP(Border Gateway Protocol )边界网关协议,用来连接Internet 上独立系统的路由选择协议.采用路径向量路由选择协议。

数据链路层: (典型设备: 网卡,网桥,交换机) 数据单元:帧 (Frame)

ARQ(Automatic Repeat-reQuest )自动重传请求协议,错误纠正协议之一,包括停止等待ARQ 协议和连续ARQ 协议,错误侦测、正面确认、逾时重传与负面确认继以重传等机制。

停止等待协议:
CSMA/CD(Carrrier Sense Multiple Access with Collision Detection)载波监听多点接入/碰撞检测协议。总线型网络,协议的实质是载波监听和碰撞检测。载波监听即发数据前先检测总线上是否有其他计算机在发送数据,如暂时不发数据,避免碰撞。碰撞检测为计算机边发送数据边检测信道上的信号电压大小。

PPP(Point-to-Ponit Protocol)点对点协议面向字节,由三部分组成:
一个将IP 数据报封装到串行链路的方法
一个用于建立、配置和测试数据链路连接的链路控制协议LCP
一套网络控制协议NCP

HDLC (High-Level Data Link Control )高级数据链路控制同步网上传输数据、面向比特的数据链路层协议。

ATM (Asynchronous Transfer Mode )异步传递方式,建立在电路交换和分组交换的基础上的一种面向连接的快速分组交换技术。 “异步”是指将ATM 信元“异步插入”到同步的 SDH 比特流中。如同步插入则用户在每帧中所占的时隙相对位置固定不变。“同步”是指网络中各链路上的比特流都是受同一非常精确的主时钟的控制。Wi-Fi 、WiMAX 、DTM 、令牌环、以太网、FDDI 、帧中继、 GPRS 、 EVDO 、HSPA 、L2TP 、ISDN

物理层:(典型设备:中继器,集线器) 数据单元:比特 (Bit)

光纤、 同轴电缆、双绞线…

TCP/IP

Transmission Control Protocol/Internet Protocol的简写,中译名为传输控制协议/因特网互联协议,又名网络通讯协议,是Internet最基本的协议、Internet国际互联网络的基础,由网络层的IP协议和传输层的TCP协议等组成(当然还有其他后来发展起来的网络协议,还包括 ARP,ICMP,IGMP,UDP,以及让域名访问成为可能的DNS,以及电脑/手机可以自动获取IP地址的DHCP。当然还有形形色色的应用层的协议如 HTTP / SMTP / FTP 等。。TCP/IP 定义了电子设备如何连入因特网,以及数据如何在它们之间传输的标准。协议采用了4层的层级结构,每一层都呼叫它的下一层所提供的协议来完成自己的需求。通俗而言:TCP负责发现传输的问题,一有问题就发出信号,要求重新传输,直到所有数据安全正确地传输到目的地。而IP是给因特网的每一台联网设备规定一个地址。

IP协议(Internet Protocol)是将多个包交换网络连接起来,它在源地址和目的地址之间传送一种称之为数据包的东西,它还提供对数据大小的重新组装功能,以适应不同网络对包大小的要求。IP协议在OSI参考模型中应用于网络层,以“数据包(Package)”为单位。其中,IP地址的定义是确认唯一端口号和路由选择的关键,IP地址相当于每台电话的电话号码,唯一且是我们互相联系的关键,因此IP协议也是网络互连的关键。

IP协议特点

  • ①IP协议是一种无连接、不可靠的分组传送服务的协议。
  • ②IP协议是点-点线路的网络层通信协议。IP协议是针对原主机-路由器、路由器-路由器、路由器-目的主机之间的数据传输的点-点线路的网络层通信协议。
  • ③IP协议屏蔽了网络在数据链路层、物理层协议与实现技术上的差异。:通过IP协议,网络层向传输层提供的是统一的IP分组,传输层不需要考虑互联网在数据链路层、物理层协议与实现技术上的差异,IP协议使得异构网络的互联变得容易了。

TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的, 基于IP的传输层协议。TCP在IP报文的协议号是6。TCP是一个超级麻烦的协议,而它又是互联网的基础。

TCP工作在网络OSI的七层模型中的第四层——Transport层(传输层),IP在第三层——Network层,ARP 在第二层——Data Link层。在第二层的数据,我们把它叫Frame(数据帧),在第三层的数据叫Packet(数据包),第四层的数据叫Segment(数据段)。 同时,我们需要简单的知道,数据从应用层发下来,会在每一层都会加上头部信息,进行封装,然后再发送到数据接收端。所以数据的发送和接收其实就是数据的封装和解封装的过程。

UDP 是User Datagram Protocol的简称, 中文名是用户数据报协议,是OSI(Open System Interconnection,开放式系统互联) 参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,IETF RFC 768是UDP的正式规范。UDP在IP报文的协议号是17。与所熟知的TCP(传输控制协议)协议一样,UDP协议直接位于IP(网际协议)协议的顶层。根据OSI(开放系统互连)参考模型,UDP和TCP都属于传输层协议。UDP协议的主要作用是将网络数据流量压缩成数据包的形式。一个典型的数据包就是一个二进制数据的传输单位。每一个数据包的前8个字节(16*4位)用来包含报头信息,剩余字节则用来包含具体的传输数据。

  • UDP是一个无连接协议,传输数据之前源端和终端不建立连接,当 UDP想传送时就简单地去抓取来自应用程序的数据,并尽可能快地把它扔到网络上。在发送端,UDP传送数据的速度仅仅是受应用程序生成数据的速度、计算机的能力和传输带宽的限制;在接收端,UDP把每个消息段放在队列中,应用程序每次从队列中读一个消息段。
  • 由于传输数据不建立连接,因此也就不需要维护连接状态,包括收发状态等,因此一台服务机可同时向多个客户机传输相同的消息。
  • UDP信息包的标题很短,只有8个字节,相对于TCP的20个字节信息包的额外开销很小。
  • 吞吐量不受拥挤控制算法的调节,只受应用软件生成数据的速率、传输带宽、源端和终端主机性能的限制。
  • UDP使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的链接状态表(这里面有许多参数)。
  • UDP是面向报文的。发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付给IP层。既不拆分,也不合并,而是保留这些报文的边界,因此,应用程序需要选择合适的报文大小。 虽然UDP是一个不可靠的协议,但它是分发信息的一个理想协议。例如,在屏幕上报告股票市场、在屏幕上显示航空信息等等。UDP也用在路由信息协议RIP(Routing Information Protocol)中修改路由表。在这些应用场合下,如果有一个消息丢失,在几秒之后另一个新的消息就会替换它。UDP广泛用在多媒体应用中,例如,Progressive Networks公司开发的RealAudio软件,它是在因特网上把预先录制的或者现场音乐实时传送给客户机的一种软件,该软件使用的RealAudio audio-on-demand protocol协议就是运行在UDP之上的协议,大多数因特网电话软件产品也都运行在UDP之上。

TCP拥塞控制原理

  • 拥塞控制:
    当网络中某一资源的需求超出了该资源所能提供的可用部分,这时网络的性能就要开始变坏,这种情况就叫做拥塞。而拥塞控制就是为了减少或者避免拥塞对网络性能的影响而做出的一种控制手段。

  • 拥塞控制思路:发送方维持一个叫做拥塞窗口的状态变量,拥塞窗口的大小取决于网络的拥塞程度,并且在动态的变化。发送方让自己的发送窗口等于拥塞窗口,如果在考虑接收方的接收能力,一般发送窗口还要小于拥塞窗口。

  • 慢开始:当主机开始发送数据的时候,由小到大的增大发送窗口,也就是由小到大的增大拥塞窗口。接收方接收到一个报文之后就回传一个确认报文,发送方每接收到一个确认报文,就将拥塞窗口加1,这样每经过一个传输轮次之后,拥塞窗口就增大一倍。

  • 拥塞避免:思路是让拥塞窗口缓慢的增大,即每经过一个往返时间RTT就把发送方的拥塞窗口加1,而不是加倍,这样拥塞窗口就是线性缓慢增加,比慢开始的增长速率缓慢的多。

  • 慢开始门限:为了防止拥塞窗口增长过大引起网络拥塞,还需要设置一个慢开始门限

    • 拥塞窗口<慢开始门限时,使用慢开始算法
    • 拥塞窗口>慢开始门限时,使用拥塞避免算法
    • 拥塞窗口=慢开始门限时,两种算法都可以

TCP/UDP区别

1. 一般区别

  • TCP是面向连接的,传输数据保证可靠性和安全性;TCP协议是非面向连接的,是不可靠但高效率的协议。
  • TCP占用资源多而UDP占用少。
  • TCP是流模式而TCP是数据报模式。(可以这样理解:TCP是面向连接的,用打电话的过程来类比,就是通信双方是互相明确的,所以进行的是“你一句我一句”的交流,TCP整个通信过程间有一个缓存区,由于通信主体明确,因此可以断断续续地进行交流,数据好比水流,知道源头和目的地,因此称为流模式。反过来,UDP是非面向连接的,好比写信的过程,假设我们只要知道佩奇的地址,我们就能写信给佩奇,而佩奇却不认识我们。这样发起通信方的身份是不明确的,每个发送端的信息都不能和别的发送端混淆,不然会造成数据失效,所以UDP要对数据进行“打包”发送,是面向报文的,就像写信需要用信封套起来,不然只发送数据甚至数据混合会变得毫无意义,就像qq群的匿名聊天,这不扯皮吗?)
  • TCP和UDP的应用场景和编程方式也有很大差别,此处不再赘述。

2. TCP的粘包和UDP的丢包

   TCP粘包现象:TCP粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。

  粘包原因:

  • 发送端:TCP默认会使用Nagle算法。而Nagle算法主要做两件事:1)只有上一个分组得到确认,才会发送下一个分组;2)收集多个小分组,在一个确认到来时一起发送。所以,正是Nagle算法造成了发送方有可能造成粘包现象。
  • 接收端:TCP接收到分组时,并不会立刻送至应用层处理,或者说,应用层并不一定会立即处理;实际上,TCP将收到的分组保存至接收缓存里,然后应用程序主动从缓存里读收到的分组。这样一来,如果TCP接收分组的速度大于应用程序读分组的速度,多个包就会被存至缓存,应用程序读时,就会读到多个首尾相接粘到一起的包。

  粘包处理:如果黏在一起的包是同一个整体,即同意部分数据分割而来的,那么就不用进行处理。如果是不同部分的数据粘到一起,就需要进行粘包解决:

  • 发送端导致:使用TCP_NODELAY选项来关闭Nagle算法。
  • 接收端导致:暂无。
  • 统一解决(应用层):可以解决接收方造成的粘包问题,还能解决发送方造成的粘包问题。
    解决方法就是循环处理:应用程序在处理从缓存读来的分组时,读完一条数据时,就应该循环读下一条数据,直到所有的数据都被处理;但是如何判断每条数据的长度呢?
    两种途径:
      1)格式化数据:每条数据有固定的格式(开始符、结束符),这种方法简单易行,但选择开始符和结束符的时候一定要注意每条数据的内部一定不能出现开始符或结束符;
           2)发送长度(推荐):发送每条数据的时候,将数据的长度一并发送,比如可以选择每条数据的前4位是数据的长度,应用层处理时可以根据长度来判断每条数据的开始和结束

  UDP丢包现象:丢包现象即使用UDP发送时,由于不可靠连接方式,收到各种因素影响,数据包可能会在接受过程中丢失一部分,从而导致数据不完整。

  UDP丢包原因:

  • 发送端:发送的包太大导致send方法无法正常切割为小包导致丢包、发送的包太大超过缓存设置也会出现对包、发送频率太快导致接收端未接受或溢出缓冲区而丢包。
  • 接收端:处理时间过长导致丢包。
  • 其他:网络等问题。

  UDP丢包处理:

  • UDP的缺陷在于丢包和乱序问题,一般视情况进行处理,而发送的时候也需要注意上述导致丢包的问题。

HTTP是一个客户端和服务器端请求和应答的标准,通常,由HTTP客户端发起一个请求,建立一个到服务器指定端口(默认是80端口)的TCP连接。HTTP服务器则在那个端口监听客户端发送过来的请求。一旦收到请求,服务器(向客户端)发回一个状态行。 HTTP协议的网页 HTTP协议的网页 HTTP使用TCP而不是UDP的原因在于(打开)一个网页必须传送很多数据,而TCP协议提供传输控制,按顺序组织数据,和错误纠正。

  通过HTTP或者HTTPS协议(HTTP协议+SSL协议)请求的资源由统一资源标示符(Uniform Resource Identifiers)(或者,更准确一些,URLs)来标识。HTTP有以下特点:

  • 简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。

  • 灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
  • 无连接:无连接的含义是限制每次连接只处理一个请求服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
  • 无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
  • 支持B/S及C/S模式。

URL是一种特殊类型的URI,包含了用于查找某个资源的足够的信息,URL,全称是UniformResourceLocator, 中文叫统一资源定位符,是互联网上用来标识某一处资源的地址。以下面这个URL为例,介绍下普通URL的各部分组成:

  http://www.cnblogs.com:8080/fzz9/index.jsp?id=30303&page=2#name

  • 协议部分:一般为HTTP或Https,后接//作为分隔符。
  • 域名部分:www.cnblogs.com为网站域名。
  • 端口号部分:此网址为8080。跟在域名后面的是端口号,域名和端口之间使用“:”作为分隔符。端口不是一个URL必须的部分,如果省略端口部分,将采用默认端口。

  • 虚拟目录部分:从域名后的第一个“/”开始到最后一个“/”为止,是虚拟目录部分。虚拟目录也不是一个URL必须的部分。
  • 参数部分:从“?”开始到“#”为止之间的部分为参数部分。本例中的参数部分为“id=30303&page=2”。不是必要部分。
  • 文件名部分:从域名后的最后一个“/”开始到后面一个“?”为止,是文件名部分,如果没有“?”,则是从域名后的最后一个“/”开始到“#”为止,是文件部分,如果没有“?”和“#”,那么从域名后的最后一个“/”开始到结束,都是文件名部分。本例中的文件名是“index.jsp”。文件名部分也不是一个URL必须的部分,如果省略该部分,则使用默认的文件名。
  • 锚部分(Fragment):从“#”开始到最后,都是锚部分。本例中的锚部分是“name”。锚部分也不是一个URL必须的部分。#是用来指导浏览器动作的,对服务器端完全无用。window.location.hash读取#值

本部分摘自:https://www.cnblogs.com/fzz9/p/8964513.html    https://www.cnblogs.com/haldis/p/4601792.html

八、http/https/http2.0

1. http

超文本传输协议

http请求头部字段:https://www.cnblogs.com/s313139232/p/7830983.html

2. https

HTTPS 是以安全为目标的 HTTP 通道,简单讲是 HTTP 的安全版,即 HTTP 下加入 SSL 层,HTTPS 的安全基础是 SSL,因此加密的详细内容就需要 SSL。

HTTPS 协议的主要作用可以分为两种:一种是建立一个信息安全通道,来保证数据传输的安全;另一种就是确认网站的真实性。 HTTPS 和 HTTP 的区别主要如下:
  • HTTPS 协议使用 ca 申请证书,由于免费证书较少,需要一定费用。
  • HTTP 是明文传输,HTTPS 则是具有安全性的 SSL 加密传输协议。
  • HTTP 和 HTTPS使用的是完全不同的连接方式,用的端口也不一样,前者是 80,后者是 443。

3. http1.0

  • 请求与响应支持 HTTP 头,增加了状态码,响应对象的一开始是一个响应状态行
  • 协议版本信息需要随着请求一起发送,支持 HEAD,POST 方法
  • 支持传输 HTML 文件以外其他类型的内容 
  • 简单快速:当客户端向服务器端发送请求时,只是简单的填写请求路径和请求方法即可,然后就可以通过浏览器或其他方式将该请求发送就行了 。
  • 灵活: HTTP 协议允许客户端和服务器端传输任意类型任意格式的数据对象
  • 无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接,采用这种方式可以节省传输时间。(当今多数服务器支持Keep-Alive功能,使用服务器支持长连接,解决无连接的问题)
  • 无状态:无状态是指协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。即客户端发送HTTP请求后,服务器根据请求,会给我们发送数据,发送完后,不会记录信息。(使用 cookie 机制可以保持 session,解决无状态的问题)

4. http1.1

  • 可以复用连接
  • 增加 pipeline:HTTP 管线化是将多个 HTTP 请求整批提交的技术,而在传送过程中不需先等待服务端的回应。管线化机制须通过永久连接(persistent connection)完成。浏览器将HTTP请求大批提交可大幅缩短页面的加载时间,特别是在传输延迟(lag/latency)较高的情况下。有一点需要注意的是,只有幂等的请求可以使用 pipeline,如 GET,HEAD 方法。
  • chunked 编码传输:该编码将实体分块传送并逐块标明长度,直到长度为 0 块表示传输结束, 这在实体长度未知时特别有用(比如由数据库动态产生的数据)
  • 引入更多缓存控制机制:如 etag,cache-control
  • 引入内容协商机制,包括语言,编码,类型等,并允许客户端和服务器之间约定以最合适的内容进行交换
  • 请求消息和响应消息都支持 Host 头域:在 HTTP1.0 中认为每台服务器都绑定一个唯一的 IP 地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个 IP 地址。因此,Host 头的引入就很有必要了。
  • 新增了 OPTIONS,PUT, DELETE, TRACE, CONNECT 方法 虽然 HTTP/1.1 已经优化了很多点,作为一个目前使用最广泛的协议版本,已经能够满足很多网络需求,但是随着网页变得越来越复杂,甚至演变成为独立的应用,HTTP/1.1 逐渐暴露出了一些问题:
  • 在传输数据时,每次都要重新建立连接,对移动端特别不友好
  • 传输内容是明文,不够安全
  • header 内容过大,每次请求 header 变化不大,造成浪费
  • keep-alive 给服务端带来性能压力 为了解决这些问题,HTTPS 和 SPDY 应运而生。

5. http2.0

  • 使用二进制分帧层:在应用层与传输层之间增加一个二进制分帧层,以此达到在不改动 HTTP 的语义,HTTP 方法、状态码、URI 及首部字段的情况下,突破HTTP1.1 的性能限制,改进传输性能,实现低延迟和高吞吐量。在二进制分帧层上,HTTP2.0 会将所有传输的信息分割为更小的消息和帧,并对它们采用二进制格式的编码,其中 HTTP1.x 的首部信息会被封装到 Headers 帧,而我们的 request body 则封装到 Data 帧里面。
  • 多路复用:对于 HTTP/1.x,即使开启了长连接,请求的发送也是串行发送的,在带宽足够的情况下,对带宽的利用率不够,HTTP/2.0 采用了多路复用的方式,可以并行发送多个请求,提高对带宽的利用率。
  • 数据流优先级:由于请求可以并发发送了,那么如果出现了浏览器在等待关键的 CSS 或者 JS 文件完成对页面的渲染时,服务器却在专注的发送图片资源的情况怎么办呢?HTTP/2.0 对数据流可以设置优先值,这个优先值决定了客户端和服务端处理不同的流采用不同的优先级策略。
  • 服务端推送:在 HTTP/2.0 中,服务器可以向客户发送请求之外的内容,比如正在请求一个页面时,服务器会把页面相关的 logo,CSS 等文件直接推送到客户端,而不会等到请求来的时候再发送,因为服务器认为客户端会用到这些东西。这相当于在一个 HTML 文档内集合了所有的资源。
  • 头部压缩:使用首部表来跟踪和存储之前发送的键值对,对于相同的内容,不会再每次请求和响应时发送。

SSL加密过程:

  • 第一步:A给出支持SSL协议版本号,一个客户端随机数(Client random,请注意这是第一个随机数),客户端支持的加密方法等信息;
  • 第二步:B收到信息后,确认双方使用的加密方法,并返回数字证书,一个服务器生成的随机数(Server random,注意这是第二个随机数)等信息;
  • 第三步:A确认数字证书的有效性,然后生成一个新的随机数(Premaster secret),然后使用数字证书中的公钥,加密这个随机数,发给B。
  • 第四步:B使用自己的私钥,获取A发来的随机数(即Premaster secret);(第三、四步就是非对称加密的过程了)
  • 第五步:A和B通过约定的加密方法(通常是AES算法),使用前面三个随机数,生成对话密钥,用来加密接下来的通信内容;

本部分摘自:https://juejin.im/post/5be935f2e51d4570813b8cf0     https://www.cnblogs.com/jztan/p/8159086.html(写的很好呦~)

九、get post区别

  • GET在浏览器回退时是无害的,而POST会再次提交请求。
  • GET产生的URL地址可以被Bookmark,而POST不可以。
  • GET请求会被浏览器主动cache,而POST不会,除非手动设置。
  • GET请求只能进行url编码,而POST支持多种编码方式。
  • GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
  • GET请求在URL中传送的参数是有长度限制的,而POST么有。(浏览器限制)
  • 对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
  • GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。(从传输的角度来说,他们都是不安全的,因为 HTTP 在网络上是明文传输的,只要在网络节点上捉包,就能完整地获取数据报文。要想安全传输,就只有加密,也就是 HTTPS
  • GET参数通过URL传递,POST放在Request body中。
  • GET产生一个TCP数据包;POST产生两个TCP数据包。(部分浏览器的行为,而不是post 必然行为)

    对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);

    而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)

GET和POST是什么?HTTP协议中的两种发送请求的方法。

HTTP是什么?HTTP是基于TCP/IP的关于数据如何在万维网中如何通信的协议。

HTTP的底层是TCP/IP。所以GET和POST的底层也是TCP/IP,也就是说,GET/POST都是TCP链接。GET和POST能做的事情是一样一样的。你要给GET加上request body,给POST带上url参数,技术上是完全行的通的,只要后端支持就好。

实际上,没有本质区别,但是由于HTTP的规定和浏览器/服务器的限制,导致他们在应用过程中体现出一些不同。(大多数)浏览器通常都会限制url长度在2K个字节,而(大多数)服务器最多处理64K大小的url。超过的部分,恕不处理。如果你用GET服务,在request body偷偷藏了数据,不同服务器的处理方式也是不同的,有些服务器会帮你卸货,读出数据,有些服务器直接忽略,所以,虽然GET可以带request body,也不能保证一定能被接收到哦。

本部分摘自:https://blog.51cto.com/13961945/2287553

十、ajax、 axios库

Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。

它的特性是:

  • 从浏览器中创建 XMLHttpRequests
  • 从 node.js 创建 http 请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求数据和响应数据
  • 取消请求
  • 自动转换 JSON 数据
  • 客户端支持防御 XSRF

axios包含所有请求方式函数的封装、

axios.get(url [,config])
axios.delete(url [,config])
axios.head(url [,config])
axios.post(url [,data [,config]])
axios.put(url [,data [,config]])
axios.patch(url [,data [,config]])

本部分摘自:https://www.jianshu.com/p/ae8e9edf4460

十一、tcp三次握手,四次挥手流程

SYN(synchronous建立联机)

ACK(acknowledgement 确认)

PSH(push传送)

FIN(finish结束)

RST(reset重置)

URG(urgent紧急)

1. 三次握手——建立TCP连接

第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。

第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack (number )=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态

第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。

为什么三次握手?

  • 防止已失效的连接请求又传送到服务器端,因而产生错误。
  • 为了实现可靠数据传输, TCP 协议的通信双方, 都必须维护一个序列号, 以标识发送出去的数据包中, 哪些是已经被对方收到的。 三次握手的过程即是通信双方相互告知序列号起始值, 并确认对方已经收到了序列号起始值的必经步骤
  • 如果只是两次握手, 至多只有连接发起方的起始序列号能被确认, 另一方选择的序列号则得不到确认

有这样一种情况,当A发送一个消息给B,但是由于网络原因,消息被阻塞在了某个节点,然后阻塞的时间超出设定的时间,A会认为这个消息丢失了,然后重新发送消息。

当A和B通信完成后,这个被A认为失效的消息,到达了B
对于B而言,以为这是一个新的请求链接消息,就向A发送确认,
对于A而言,它认为没有给B再次发送消息(因为上次的通话已经结束)所有A不会理睬B的这个确认,但是B则会一直等待A的消息

这就导致了B的时间被浪费(对于服务器而言,CPU等资源是一种浪费),这样是不可行的,这就是为什么不能两次握手的原因了。

2. 四次挥手——断开TCP连接

先由客户端向服务器端发送一个FIN,请求关闭数据传输。

当服务器接收到客户端的FIN时,向客户端发送一个ACK,其中ack的值等于FIN+SEQ

然后服务器向客户端发送一个FIN,告诉客户端应用程序关闭。

当客户端收到服务器端的FIN是,回复一个ACK给服务器端。其中ack的值等于FIN+SEQ

为什么要4次挥手?

  • 确保数据能够完整传输。
  • 当被动方收到主动方的FIN报文通知时,它仅仅表示主动方没有数据再发送给被动方了。
  • 但未必被动方所有的数据都完整的发送给了主动方,所以被动方不会马上关闭SOCKET,它可能还需要发送一些数据给主动方后,
  • 再发送FIN报文给主动方,告诉主动方同意关闭连接,所以这里的ACK报文和FIN报文多数情况下都是分开发送的。

为什么需要TIME_WAIT状态 

  • 可靠的终止TCP连接 
  • 保证让迟来的TCP报文段有足够的时间被识别并丢弃

SYN攻击

在三次握手过程中,Server发送SYN-ACK之后,收到Client的ACK之前的TCP连接称为半连接(half-open connect),此时Server处于SYN_RCVD状态,当收到ACK后,Server转入ESTABLISHED状态。SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server回复确认包,并等待Client的确认,由于源地址是不存在的,因此,Server需要不断重发直至超时,这些伪造的SYN包将长时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络堵塞甚至系统瘫痪。SYN攻击时一种典型的DDOS攻击,检测SYN攻击的方式非常简单,即当Server上有大量半连接状态且源IP地址是随机的,则可以断定遭到SYN攻击了。

本部分摘自:https://www.cnblogs.com/lms0755/p/9053119.html

十二、跨域

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

- 不同的域名 (比如在网站 example.com 请求 api.com)

- 不同的子域名 (比如在网站 example.com 请求 api.example.com)

- 不同的端口 (比如在网站 example.com 请求 example.com:3001)

- 不同协议 (比如在网站 https://example.com 请求 http://example.com)

1. JSONP

浏览器只对XHR(XMLHttpRequest)请求有同源请求限制,而对script标签src属性、link标签ref属性和img标签src属性没有这这种限制,利用这个“漏洞”就可以很好的解决跨域请求。JSONP就是利用了script标签无同源限制的特点来实现的,当向第三方站点请求时,我们可以将此请求放在<script>标签的src属性里,这就如同我们请求一个普通的JS脚本,可以自由的向不同的站点请求:

<script src="http://www.b.com/request?para1=1"></script>

  • script标签设置src属性为请求的地址,并判断回调函数作为参数
  • 服务端构建JS脚本,传递返回给客户端的数据
  • 客户端在回调函数中解析服务器生成的数据

只支持GET,不支持POST请求

/**
 * JSONP请求工具
 * @param url 请求的地址
 * @param data 请求的参数
 * @returns {Promise<any>}
 */
const request = ({url, data}) => {
  return new Promise((resolve, reject) => {
    // 处理传参成xx=yy&aa=bb的形式
    const handleData = (data) => {
      const keys = Object.keys(data)
      const keysLen = keys.length
      return keys.reduce((pre, cur, index) => {
        const value = data[cur]
        const flag = index !== keysLen - 1 ? '&' : ''
        return `${pre}${cur}=${value}${flag}`
      }, '')
    }
    // 动态创建script标签
    const script = document.createElement('script')
    // 接口返回的数据获取
    window.jsonpCb = (res) => {
      document.body.removeChild(script)
      delete window.jsonpCb
      resolve(res)
    }
    script.src = `${url}?${handleData(data)}&cb=jsonpCb`
    document.body.appendChild(script)
  })
}
// 使用方式
request({
  url: 'http://localhost:9871/api/jsonp',
  data: {
    // 传参
    msg: 'helloJsonp'
  }
}).then(res => {
  console.log(res)
})
//它的基本思想是,网页通过添加一个<script>元素,向服务器请求JSON数据,这种做法不受同源政策限制;服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。
//首先,网页动态插入<script>元素,由它向跨源网址发出请求。
function addScriptTag(src) {
  var script = document.createElement('script');
  script.setAttribute("type","text/javascript");
  script.src = src;
  document.body.appendChild(script);
}

window.onload = function () {
  addScriptTag('http://example.com/ip?callback=foo');
}

function foo(data) {
  console.log('Your public IP address is: ' + data.ip);
};
//上面代码通过动态添加<script>元素,向服务器example.com发出请求。注意,该请求的查询字符串有一个callback参数,用来指定回调函数的名字,这对于JSONP是必需的。
//服务器收到这个请求以后,会将数据放在回调函数的参数位置返回。

2. CORS(HTML5支持)

CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)

浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。

只要同时满足以下两大条件,就属于简单请求。
(1) 请求方法是以下三种方法之一:

  • HEAD
  • GET
  • POST

(2)HTTP的头信息不超出以下几种字段:

  • Accept
  • Accept-Language
  • Content-Language
  • Last-Event-ID
  • Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

Access-Control-Allow-Origin

这个头部信息由服务器返回,用来明确指定那些客户端的域名允许访问这个资源

简单请求

浏览器会在在header信息里面多加一个字段:
key:origin 
value:协议+域名+端口(如https://localhost:8080)

服务器根据对象里的origin值来决定是否同意这次请求

如果请求通过
请求通过后,服务器会在header里多增加几个字段:

Access-Control-Allow-Origin: https://localhost:8080
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: Token

非简单请求

非简单请求的方法就是Put,Delete,或者Content-Type是application/json

非简单请求在发出CORS请求之前,会增加一次HTTP查询请求,也叫预检请求
预检请求成功了,浏览器才能发出XMLHttpRequest,否则报错

如果浏览器发现这是一个非简单请求
就会先发送一个预检请求:

OPTIONS /cors HTTP/1.1
Origin: http://localhost:8088
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: token

预测请求的方法名叫OPTIONS
Origin和简单请求一样
Access-Control-Request-Method是请求方法
Access-Control-Request-Headers是额外发送的头信息字段
(tip:预检请求一般缓存下来,以便不需要在每次请求都发送)

如果预检请求通过
我们来看下服务器发出的回应

HTTP/1.1 200 OK
Date: Nov, 01 Dec 2017 01:15:39 GMT
Server: Apache/2.0.61 (Unix)
Access-Control-Allow-Origin: http://localhost:8088
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: token
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Content-Length: 0
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/plain

如果预检请求失败
服务器会返回一个HTTP回应(没有CORS的头信息字段)
并在console打出not allowed by Access-Control-Allow-Origin异常

预检请求通过以后
浏览器发每次出的CORS请求就和简单请求一样
会有一个origin字段
服务器每次回应都会有Access-Control-Allow-Origin头信息字段

3、 document.domain + iframe跨域

此方案仅限主域相同,子域不同的跨域应用场景。

实现原理:两个页面都通过js强制设置document.domain为基础主域,就实现了同域。

父窗口(http://www.demo.com/a.html)
<iframe id="iframe" src="http://child.demo.com/b.html"></iframe>
<script>
    document.domain = 'demo.com';
    var user = 'admin';
</script>
子窗口:(http://child.demo.com/b.html)
<script>
    document.domain = 'demo.com';
    // 获取父窗口中变量
    alert('get js data from parent ---> ' + window.parent.user);
</script>

4、 location.hash + iframe

实现原理: a欲与b跨域相互通信,通过中间页c来实现。 三个页面,不同域之间利用iframe的location.hash传值,相同域之间直接js访问来通信。

具体实现:A域:a.html -> B域:b.html -> A域:c.html,a与b不同域只能通过hash值单向通信,b与c也不同域也只能单向通信,但c与a同域,所以c可通过parent.parent访问a页面所有对象。

实现原理: a欲与b跨域相互通信,通过中间页c来实现。 三个页面,不同域之间利用iframe的location.hash传值,相同域之间直接js访问来通信。

具体实现:A域:a.html -> B域:b.html -> A域:c.html,a与b不同域只能通过hash值单向通信,b与c也不同域也只能单向通信,但c与a同域,所以c可通过parent.parent访问a页面所有对象。

5、 window.name + iframe跨域

window.name属性的独特之处:name值在不同的页面(甚至不同域名)加载后依旧存在,并且可以支持非常长的 name 值(2MB)。

6、 postMessage跨域

postMessage是HTML5 XMLHttpRequest Level 2中的API,且是为数不多可以跨域操作的window属性之一,它可用于解决以下方面的问题:
a.) 页面和其打开的新窗口的数据传递
b.) 多窗口之间消息传递
c.) 页面与嵌套的iframe消息传递
d.) 上面三个场景的跨域数据传递

用法:postMessage(data,origin)方法接受两个参数
data: html5规范支持任意基本类型或可复制的对象,但部分浏览器只支持字符串,所以传参时最好用JSON.stringify()序列化。
origin: 协议+主机+端口号,也可以设置为"*",表示可以传递给任意窗口,如果要指定和当前窗口同源的话设置为"/"。

<iframe id="iframe" src="http://www.demo2.com/b.html" style="display:none;"></iframe>
<script>       
    var iframe = document.getElementById('iframe');
    iframe.onload = function() {
        var data = {
            name: 'aym'
        };
        // 向domain2传送跨域数据
        iframe.contentWindow.postMessage(JSON.stringify(data), 'http://www.demo2.com');
    };

    // 接受domain2返回数据
    window.addEventListener('message', function(e) {
        alert('data from demo2 ---> ' + e.data);
    }, false);
</script>

<script>
    // 接收domain1的数据
    window.addEventListener('message', function(e) {
        alert('data from demo1 ---> ' + e.data);

        var data = JSON.parse(e.data);
        if (data) {
            data.number = 16;

            // 处理后再发回domain1
            window.parent.postMessage(JSON.stringify(data), 'http://www.demo1.com');
        }
    }, false);
</script>

7、 nginx代理跨域
8、 nodejs中间件代理跨域
9、 WebSocket协议跨域

本部分摘自:https://segmentfault.com/a/1190000015597029?utm_source=tag-newest 

                     https://segmentfault.com/a/1190000017867312?utm_source=tag-newest   

                     https://www.cnblogs.com/sdcs/p/8484905.html

十三、前端安全XSS、CSRF

1. XSS——跨站脚本攻击

其原理是攻击者向有 XSS漏洞的网站中输入(传入)恶意的HTML代码,当其它用户浏览该网站时,这段HTML代码会自动执行,从而达到攻击的目的。如,盗取用户 Cookie、破坏页面的正常结构,插入广告等恶意内容、重定向到其它网站,D-doss攻击等;XSS攻击类似于SQL注入攻击,攻击之前,我们先找到一个存在XSS漏洞的网站。理论上,所有可输入的地方没有对输入数据进行处理的话,都会存在XSS漏洞,漏洞的危害取决于攻击代码的威力。

反射型
发出请求时,XSS代码出现在url中,作为输入提交到服务器端,服务器端解析后响应,XSS代码随响应内容一起传回给浏览器,最后浏览器解析执行XSS代码。这个过程像一次反射,所以叫反射型XSS。
存储型
存储型XSS和反射型XSS的差别在于,提交的代码会存储在服务器端(数据库、内存、文件系统等),下次请求时目标页面时不用再提交XSS代码。
防范措施

设置httponly,对cookie进行保护

编码:对用户输入的数据进行 HTML Entity 编码。Encode的作用是将等一些字符进行转化,使得浏览器在最终输出结果上是一样的。

过滤:移除用户输入的和事件相关的属性。如onerror可以自动触发攻击,还有onclick等。移除用户输入的Style节点、Script节点、Iframe节点。(尤其是Script节点,它可是支持跨域的呀,一定要移除)。

校正:避免直接对HTML Entity进行解码。使用DOM Parse转换,校正不配对的DOM标签。

2. CSRF——跨站点伪造请求

该攻击可以在受害者毫不知情的情况下以受害者名义伪造请求发送给受攻击站点,从而在未授权的情况下执行在权限保护之下的操作,具有很大的危害性。具体来讲,可以这样理解CSRF攻击:攻击者盗用了你的身份,以你的名义发送恶意请求,对服务器来说这个请求是完全合法的,但是却完成了攻击者所期望的一个操作,比如以你的名义发送邮件、发消息,盗取你的账号,添加系统管理员,甚至于购买商品、虚拟货币转账等。

  • 用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A;
  • 在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登录网站A成功,可以正常发送请求到网站A;
  • 用户未退出网站A之前,在同一浏览器中,打开一个TAB页访问网站B;
  • 网站B接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点A;
  • 浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。网站A并不知道该请求其实是由B发起的,所以会根据用户C的Cookie信息以C的权限处理该请求,导致来自网站B的恶意代码被执行。

防范措施

方法一、Token 验证:(用的最多)

服务器发送给客户端一个token;
客户端提交的表单中带着这个token。
如果这个 token 不合法,那么服务器拒绝这个请求。
方法二:隐藏令牌:

把 token 隐藏在 http 的 head头中。

方法二和方法一有点像,本质上没有太大区别,只是使用方式上有区别。

方法三、Referer 验证:

Referer 指的是页面请求来源。意思是,只接受本站的请求,服务器才做响应;如果不是,就拦截。

CSRF 和 XSS 的区别
区别一:
CSRF:需要用户先登录网站A,获取 cookie。

XSS:不需要登录。

区别二:(原理的区别)
CSRF:是利用网站A本身的漏洞,去请求网站A的api。

XSS:是向网站 A 注入 JS代码,然后执行 JS 里的代码,篡改网站A的内容

本部分摘自:https://blog.csdn.net/m0_37686205/article/details/90030588

十四、websocket

 websocket是HTML5的一个新协议,它允许服务端向客户端传递信息,实现浏览器和客户端双工通信。

服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。

  • 与 HTTP 协议有着良好的兼容性。默认端口也是 80 和 443 ,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。 
  • 建立在TCP协议基础之上,和http协议同属于应用层
  • 数据格式比较轻量,性能开销小,通信高效。 
  • 可以发送文本,也可以发送二进制数据。 
  • 没有同源限制,客户端可以与任意服务器通信
  • 协议标识符是ws(如果加密,则为wss),服务器网址就是 URL,如ws://localhost:8023

本部分摘自:https://juejin.im/post/5cacb459f265da03a00fb2fe

十五、Http请求中的keep-alive

传统的Http应用里都是一次TCP连接一次request。

这种情况下效率有点低:

  • 服务端负载增加,每个请求过来都得占用端口
  • 客户端或服务端对客户端连接数的限制(chrome 限制是6个)
    这种情况很多,比如网页加载对于这个case的处理就是使用将静态资源放置到不同Domain或者压缩打包减少数量来提高效率
  • 短连接

    所谓短连接,就是每次请求一个资源就建立连接,请求完成后连接立马关闭。每次请求都经过“创建tcp连接->请求资源->响应资源->释放连接”这样的过程

  • 长连接

    所谓长连接(persistent connection),就是只建立一次连接,多次资源请求都复用该连接,完成后关闭。要请求一个页面上的十张图,只需要建立一次tcp连接,然后依次请求十张图,等待资源响应,释放连接。

  • 并行连接

    所谓并行连接(multiple connections),其实就是并发的短连接。

(1) client发出的HTTP请求头需要增加Connection:keep-alive字段

(2) Web-Server端要能识别Connection:keep-alive字段,并且在http的response里指定Connection:keep-alive字段,告诉client,我能提供keep-alive服务,并且"应允"client我暂时不会关闭socket连接

在HTTP/1.0里,为了实现client到web-server能支持长连接,必须在HTTP请求头里显示指定

Connection:keep-alive

在HTTP/1.1里,就默认是开启了keep-alive,要关闭keep-alive需要在HTTP请求头里显示指定

Connection:close

现在大多数浏览器都默认是使用HTTP/1.1,所以keep-alive都是默认打开的。一旦client和server达成协议,那么长连接就建立好了。

客户端和服务端在建立连接并完成request后并不会立即断开TCP连接,而是在下次request来临时复用这次TCP连接。但是这里也必须要有TCP连接的timeout时间限制。不然会造成服务端端口被长期占用释放不了。

对于不适用keepalive的request来说,不管是客户端还是服务端都是通过TCP的链接的断开知道request的结束(TCP 挥手时会check 数据包的 seq, 保证数据完整性)。
支持keepalive后,如何知道request结束了呢?
在Http1.1的版本里, 解决方案是request 和reponse里使用contentLength来帮助确认是否收到全部数据。

另一个问题就是在使用keepalive的情况,客户端依然有同时发送多个请求的情况,比如网页加载是需要同时load多个静态资源。比如 浏览器默认最大连接数是6,现在有十个资源同时加载,那么这十个里会有6个并行,4个与前6个串行。

在keepalive里有个问题就是如果能知道每个repose与其对应的request的话,并发的请求可以只需要一次TCP连接,这也就是http2.0实现的多路复用

十六、网络分层

 

本部分摘自(图是别人的,画的巨好,但是没找到原作者):https://www.cnblogs.com/kevingrace/p/5909719.html

十七、即时通信,除了Ajax和websocket

长轮询

十八、模块化,commonJS,es6,cmd,amd

AMD、CMD、CommonJs是ES5中提供的模块化编程的方案,import/export是ES6中新增的。

1. AMD-异步模块定义

AMD是RequireJS在推广过程中对模块定义的规范化产出,它是一个概念,RequireJS是对这个概念的实现,就好比JavaScript语言是对ECMAScript规范的实现。AMD是一个组织,RequireJS是在这个组织下自定义的一套脚本语言。RequireJS:是一个AMD框架,可以异步加载JS文件,按照模块加载方法,通过define()函数定义,第一个参数是一个数组,里面定义一些需要依赖的包,第二个参数是一个回调函数,通过变量来引用模块里面的方法,最后通过return来输出。

2. CMD---是SeaJS在推广过程中对模块定义的规范化产出,是一个同步模块定义,是SeaJS的一个标准,SeaJS是CMD概念的一个实现,SeaJS是淘宝团队提供的一个模块开发的js框架.

3. CommonJS规范---是通过module.exports定义的,在前端浏览器里面并不支持module.exports,通过node.js后端使用的。Nodejs端是使用CommonJS规范的,前端浏览器一般使用AMD、CMD、ES6等定义模块化开发的。

3. ES6特性,模块化---export/import对模块进行导出导入的。

AMD推崇依赖前置,在定义模块的时候就要声明其依赖的模块 
CMD推崇就近依赖,只有在用到某个模块的时候再去require 

很多人说requireJS是异步加载模块,SeaJS是同步加载模块,这么理解实际上是不准确的,其实加载模块都是异步的,只不过AMD依赖前置,js可以方便知道依赖模块是谁,立即加载,而CMD就近依赖,需要使用把模块变为字符串解析一遍才知道依赖了那些模块,这也是很多人诟病CMD的一点,牺牲性能来带来开发的便利性,实际上解析模块用的时间短到可以忽略

posted @ 2019-07-30 17:18  程序媛小白的学习之路  阅读(568)  评论(0编辑  收藏  举报