计算机网络相关知识

1、常见状态码

1. 消息

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

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:语义有误,当前请求没法被服务器理解。除非进行修改,不然客户端不该该重复提交这个请求。请求参数有误。html

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

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

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

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

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

406 Not Acceptable:请求的资源的内容特性没法知足请求头中的条件,于是没法生成响应实体。ios

5. 服务器错误

500 Internal Server Error:服务器遇到了一个不曾预料的情况,致使了它没法完成对请求的处理。通常来讲,这个问题都会在服务器端的源代码出现错误时出现。nginx

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

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 版本。这暗示着服务器不能或不肯使用与客户端相同的版本。响应中应当包含一个描述了为什么版本不被支持以及服务器支持哪些协议的实体。

2、缓存

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.

3、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并返回数据。

本部分摘自:http://www.javashuo.com/article/p-pmqrabgg-cs.html

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

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

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

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

5、DNS是怎么解析的

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

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

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

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

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

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

六、若是用的是转发模式,此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服务器创建连接。

6、cdn

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

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

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

协议数据单元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读取#值

本部分摘自:http://www.javashuo.com/article/p-ewsekudn-dm.html    http://www.javashuo.com/article/p-fvcfqfjo-cv.html

8、http/https/http2.0

1. http

超文本传输协议

http请求头部字段:http://www.javashuo.com/article/p-qrnsonao-cy.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);(第3、四步就是非对称加密的过程了)
  • 第五步:A和B经过约定的加密方法(一般是AES算法),使用前面三个随机数,生成对话密钥,用来加密接下来的通讯内容;

本部分摘自:http://www.javashuo.com/article/p-axrsxogg-dh.html     http://www.javashuo.com/article/p-vurbdisw-cr.html(写的很好呦~)

9、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

10、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

11、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攻击了。

本部分摘自:http://www.javashuo.com/article/p-gdgxchwo-cd.html

12、跨域

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

- 不一样的域名 (好比在网站 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头信息字段

三、 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>

四、 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页面全部对象。

五、 window.name + iframe跨域

window.name属性的独特之处:name值在不一样的页面(甚至不一样域名)加载后依旧存在,而且能够支持很是长的 name 值(2MB)。

六、 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>

七、 nginx代理跨域
八、 nodejs中间件代理跨域
九、 WebSocket协议跨域

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

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

                     http://www.javashuo.com/article/p-vwlsbjnn-br.html

十3、前端安全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的恶意代码被执行。

防范措施

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

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

把 token 隐藏在 http 的 head头中。

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

方法3、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

十4、websocket

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

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

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

本部分摘自:http://www.javashuo.com/article/p-qqicfccz-ec.html

十5、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实现的多路复用

十6、网络分层

 

本部分摘自(图是别人的,画的巨好,可是没找到原做者):http://www.javashuo.com/article/p-rhbsanol-bo.html

十7、即时通讯,除了Ajax和websocket

长轮询

十8、模块化,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的一点,牺牲性能来带来开发的便利性,实际上解析模块用的时间短到能够忽略

相关文章
相关标签/搜索