骚年,渴望力量吗,http知识,你要的都在这里

1.HTTP有几个版本?

HTTP有三个版本,HTTP/0.9 ,HTTP/1.0, HTTP/1.1 ,HTTP/2。前端

2.各个版本的区别改进有哪些?

  • HTTP/0.9

只有一个命令GET,而且服务器只能回应HTML格式的字符串,不能回应别的格式。编程

  • HTTP/1.0

除了GET命令,还引入了POST命令和HEAD命令,任何格式的内容均可以发送,除了数据部分,每次通讯都必须包括头信息(HTTP header),新增功能还包括状态码(status code)、多字符集支持、多部分发送(multi-part type)、权限(authorization)、缓存(cache)、内容编码(content encoding)。TCP链接只能发送一个请求,发送数据完毕,链接就关闭,若是还要请求其余资源,就必须再新建一个链接,为了解决这个问题,引入了一个非标准的Connection字段——Connection: keep-alive,Connection: keep-alive,服务器一样回应这个字段——Connection: keep-alive浏览器

  • HTTP/1.1

引入了持久链接(persistent connection),即TCP链接默认不关闭,能够被多个请求复用,不用声明Connection: keep-alive。同时还引入了管道机制(pipelining),即在同一个TCP链接里面,客户端能够同时发送多个请求,可是服务器仍是按照顺序,先回应A请求,完成后再回应B请求。同时1.1版还新增了许多动词方法:PUT、PATCH、HEAD、 OPTIONS、DELETE。特别的是头信息确定是文本(ASCII编码),而数据体能够是文本,也能够是二进制。缓存

  • HTTP/2

HTTP/2是一个完全的二进制协议,头信息和数据体都是二进制,而且统称为"帧"(frame):头信息帧和数据帧。 在头信息还引入了头信息压缩机制(header compression)。一方面,头信息使用gzip或compress压缩后再发送 HTTP/2 复用TCP链接,在一个链接里,客户端和浏览器均可以同时发送多个请求或回应,并且不用按照顺序一一对应,这样就避免了"队头堵塞"。bash

3.新增的状态码有哪些?各表明什么意思?

  • 2开头的:

200确定是请求成功,返回数据。
201 (已建立) 请求成功而且服务器建立了新的资源。
202 (已接受) 服务器已接受请求,但还没有处理。
203 (非受权信息) 服务器已成功处理了请求,但返回的信息可能来自另外一来源。
204 (无内容) 服务器成功处理了请求,但没有返回任何内容。
205 (重置内容) 服务器成功处理了请求,但没有返回任何内容。
206 (部份内容) 服务器成功处理了部分 GET 请求。服务器

  • 3开头的:

3xx (重定向) 表示要完成请求,须要进一步操做。 一般,这些状态代码用来重定向。
300 (多种选择) 针对请求,服务器可执行多种操做。 服务器可根据请求者 (user agent) 选择一项操做,或提供操做列表供请求者选择。
301 (永久移动) 请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。
302 (临时移动) 服务器目前从不一样位置的网页响应请求,但请求者应继续使用原有位置来进行之后的请求。
303 (查看其余位置) 请求者应当对不一样的位置使用单独的 GET 请求来检索响应时,服务器返回此代码。
304 (未修改) 自从上次请求后,请求的网页未修改过。服务器返回此响应时,不会返回网页内容。客户端一般会缓存访问过的资源,经过提供一个头信息指出客户端但愿只返回在指定日期以后修改的资源 。
305 (使用代理) 请求者只能使用代理访问请求的网页。 若是服务器返回此响应,还表示请求者应使用代理。
307 (临时重定向) 服务器目前从不一样位置的网页响应请求,但请求者应继续使用原有位置来进行之后的请求。cookie

  • 4开头的:

4xx(请求错误) 这些状态代码表示请求可能出错,妨碍了服务器的处理。 400 (错误请求) 服务器不理解请求的语法。
401 (未受权) 请求要求身份验证。 对于须要登陆的网页,服务器可能返回此响应。
403 (禁止) 服务器拒绝请求。
404 (未找到) 服务器找不到请求的网页。
405 (方法禁用) 禁用请求中指定的方法。
406 (不接受) 没法使用请求的内容特性响应请求的网页。
407 (须要代理受权) 此状态代码与 401(未受权)相似,但指定请求者应当受权使用代理。
408 (请求超时) 服务器等候请求时发生超时。
409 (冲突) 服务器在完成请求时发生冲突。 服务器必须在响应中包含有关冲突的信息。
410 (已删除) 若是请求的资源已永久删除,服务器就会返回此响应。
411 (须要有效长度) 服务器不接受不含有效内容长度标头字段的请求。
412 (未知足前提条件) 服务器未知足请求者在请求中设置的其中一个前提条件。
413 (请求实体过大) 服务器没法处理请求,由于请求实体过大,超出服务器的处理能力。
414 (请求的 URI 过长) 请求的 URI(一般为网址)过长,服务器没法处理。
415 (不支持的媒体类型) 请求的格式不受请求页面的支持。
416 (请求范围不符合要求) 若是页面没法提供请求的范围,则服务器会返回此状态代码。
417 (未知足指望值) 服务器未知足"指望"请求标头字段的要求。网络

  • 5开头的:

5xx(服务器错误)这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误多是服务器自己的错误,而不是请求出错。 500 (服务器内部错误) 服务器遇到错误,没法完成请求。
501 (还没有实施) 服务器不具有完成请求的功能。 例如,服务器没法识别请求方法时可能会返回此代码。
502 (错误网关) 服务器做为网关或代理,从上游服务器收到无效响应。
503 (服务不可用) 服务器目前没法使用(因为超载或停机维护)。 一般,这只是暂时状态。
504 (网关超时) 服务器做为网关或代理,可是没有及时从上游服务器收到请求。
505 (HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。
(前端这个时候就能够甩锅了,不是我这边的问题)socket

4. 何时会出现304状态码?

若是要知道何时出现304状态码,那么咱们就要从缓存机制讲起了。tcp

经过在这里看,知道本身日常使用的网页请求文件是怎么样缓存的

下面的图片标志有误,请求头跟返回头的标志位置要换过来

缓存机制分为:强制缓存跟协商缓存,以及在进行协商缓存前的启发式缓存,其中强制缓存优先级高于协商缓存.

  • 强制缓存

对于强制缓存,服务器响应的header中会用两个字段来代表 Expires和Cache-Control。

Expires

Exprires的值为服务端返回的数据到期时间。当再次请求时的请求时间小于返回的此时间,则直接使用缓存数据 Expires是HTTP/1.0中的定义缓存的字段,它规定了缓存过时的一个绝对时间,Expires是HTTP1.0的产物,故如今大多数使用Cache-Control替代。Expires有一个很大的弊端,就是它返回的是服务器的时间,但判断的时候用的倒是客户端的时间,这就致使Expires很被动,由于用户有可能改变客户端的时间,致使缓存时间判断出错,这也是引入Cache-Control:max-age指令的缘由之一。

Cache-Control

Cache-Control是HTTP/1.1定义的关于缓存的字段,其中Cache-Control的max-age属性规定了缓存过时的一个相对时间。优先级上固然是版本高的优先了,max-age > Expires。

例如:当cache-Control:max-age=300(以秒为单位)时,则表明在这个请求正确返回时间(浏览器也会记录下来)的5分钟内再次加载资源,就会命中强缓存,这个时候浏览器请求会返回200成功。

若是是在Chrome浏览器会返回灰色200(from disk cache)或是200 OK (from memory cache)

若是是在Firefox浏览器会返回一个灰色的200状态码。

这里介绍一下memory cache 跟disk cache的区别

先打开个人博客,打开network看一下加载的资源

from memory cache 表明使用内存中的缓存

from disk cache 则表明使用的是硬盘中的缓存

浏览器读取缓存的顺序为memory –> disk。Chrome会根据本地内存的使用率来决定缓存存放在哪,若是内存使用率低,放在磁盘里面,内存的使用率很高会暂时放在内存里面。这就能够比较合理的解释了为何同一个资源有时是from memory cache有时是from disk cache的问题了。

固然 cache-control不仅是只有max-age这个属性,还有如下经常使用的几个属性:

public:全部内容都将被缓存(客户端和代理服务器均可缓存)。具体来讲响应可被任何中间节点缓存,如 Browser <-- proxy1 <-- proxy2 <-- Server,中间的proxy能够缓存资源,好比下次再请求同一资源proxy1直接把本身缓存的东西给 Browser 而再也不向proxy2要。

private:Cache-Control的默认取值,全部内容只有客户端能够缓存。具体来讲,表示中间节点不容许缓存,对于Browser <-- proxy1 <-- proxy2 <-- Server,proxy 会老老实实把Server 返回的数据发送给proxy1,本身不缓存任何数据。当下次Browser再次请求时proxy会作好请求转发而不是自做主张给Browser本身缓存的数据。

no-cache:客户端缓存内容,是否使用缓存则须要通过协商缓存来验证决定。表示不使用 Cache-Control的缓存控制方式作前置验证,而是使用 Etag 或者Last-Modified字段来控制缓存。须要注意的是,no-cache这个名字有一点误导。设置了no-cache以后,并非说浏览器就再也不缓存数据,只是浏览器在使用缓存数据时,须要先确认一下数据是否还跟服务器保持一致。

简单来讲:就是直接进入协商缓存,不使用expire跟cache-control的max-age验证,直接向服务端请求确认

no-store:全部内容都不会被缓存,即不使用强制缓存,也不使用协商缓存

max-age:max-age=xxx (xxx is numeric)表示缓存内容将在xxx秒后失效,表示资源在本地缓存的最大时间,

s-maxage(单位为s):同max-age,只用于共享缓存(好比CDN缓存)。好比当s-maxage=60时,在这60秒中,即便更新了CDN的内容,浏览器也不会进行请求。max-age用于普通缓存,而s-maxage用于代理缓存。s-maxage的优先级高于max-age。若是存在s-maxage,则会覆盖掉max-age和Expires header。

  • 协商缓存

当expire过时而且max-age(s-max-age)超时了 ,或者直接设置no-cache了,那么会使用协商缓存。

经过如下这两个字段:If-None-Match(只能精确到秒)和If-Modified-Since(精确到毫秒) 进行协商判断是否使用缓存

If-None-Match(只要修改文件,资源惟一标识就会发生变化)和If-Modified-Since(只能精确到秒)ETag的优先级比Last-modified更高 ,若是有Etag,那么就比较Etag,不比较Last-modified,若是Etag没有发生改变,那么直接返回304 状态码使用缓存,若是Etag改变了,则返回304; 若是Etag不存在,则比较Last-modified,若是Last-modified没有改变 则返回304,告诉浏览器继续使用缓存,若是Last-modified改变了,那么返回状态码200返回新内容

既然已经有Last-modified了,那么为啥还要有Etag呢,缘由就是:

Etag的出现主要是为了解决几个Last-Modified比较难解决的问题:

  1. Last-Modified标注的最后修改只能精确到秒级,若是某些文件在1秒钟之内,被修改屡次的话,它将不能准确标注文件的修改时间。
  2. 若是某些文件会被按期生成,当有时内容并无任何变化,但Last-Modified却改变了,致使文件无法使用缓存。
  3. 有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形。

可是使用Etag也不是必须的,由于使用Etag有可能会带来性能浪费的问题

一般状况下,ETag更相似于资源指纹(fingerprints),若是资源发生变化了就会生成一个新的指纹,这样能够快速的比较资源的变化。在服务器端实现中,不少状况下并不会用哈希来计算ETag,这会严重浪费服务器端资源,不少网站默认是禁用ETag的。有些状况下,能够把ETag退化,好比经过资源的版本或者修改时间Last-modified来生成ETag,因此有来Last-modified为标准的Etag,其实就不必再使用Last-modified来,除非是不存在Etag,才使用Last-modified来进行判断。

在返回的响应头是:

ETag: "5be7d50a-30e"
Last-Modified: Sun, 11 Nov 2018 07:06:50 GMT
复制代码

在发送的请求头是:

If-Modified-Since: Sun, 11 Nov 2018 07:06:50 GMT
If-None-Match: W/"5be7d50a-30e" 
复制代码

服务器经过这两个字段来判断资源是否有修改,若是有修改则返回状态码200和新的内容,该咋处理就咋处理(至关于首次访问这个文件了)

若是没有修改,返回状态码304,若是浏览器发现返回304,因而知道了本地缓存虽然过时但仍然能够用,因而加载本地缓存。而后根据新的返回的响应头来设置缓存。

这个就能回答到上面的问题,304状态码是怎么来的:因为协商请求,对比服务器的内容跟时间未发生改变,返回304状态码,浏览器继续使用本地缓存。

  • 启发式缓存

启发式缓存阶段是在没有强制缓存时候,进入协商缓存前的一个阶段,是浏览器使用的默认缓存协议

Cache-Control: public
Date:Tue, 28 Nov 2018 12:26:41 GMT
Last-Modified: Sun, 11 Nov 2018 07:06:50 GMT
Vary:Accept-Encoding
复制代码

根据响应头中2个时间字段 Date 和 Last-Modified 之间的时间差值,取其值的10%做为缓存时间周期。若是请求时间在 从Last-Modified算起加上这个时间周期 的时间之内,则使用默认缓存,若是超过,则进入协商缓存。

5. 总结下跟缓存有关的首部字段以及各类关系?

  • Pragma HTTP1.0时的遗留字段,当值为"no-cache"时强制验证缓存
  • ETag 服务器生成资源的惟一标识,由服务端返回给客户端
  • Last-Modified 服务器资源的最后一次的修改时间,由服务端返回给客户端, Last-Modified有几个缺点:无法准确的判断资源是否真的修改了,好比某个文件在1秒内频繁更改了屡次,根据Last-Modified的时间(单位是秒)是判断不出来的,再好比,某个资源只是修改了,但实际内容并无发生变化,Last-Modified也没法判断出来,所以在HTTP/1.1中还推出了ETag这个字段,只要修改了文件,Etag资源惟一标识就会发生变化。
  • If-None-Match 客户端存下的服务器资源的惟一表示,由客户端发送给服务端
  • If-Modified-Since 客户端存下的服务器资源的最后一次的修改时间,由客户端发送给服务端
  • vary Vary用来作什么的呢?试想这么一个场景:在某个网页中网站提供给移动端的内容是不一样的,怎么让缓存服务器区分移动端和PC端呢?不知道你是否注意,浏览器在每次请求都会携带UA字段来代表来源,因此咱们能够利用User-Agent字段来区分不一样的客户端,用法以下:
Vary: User-Agent
复制代码

好比,源服务器启用了gzip压缩,但用户使用了比较旧的浏览器,不支持压缩,缓存服务器如何返回?就能够这么设定:

Vary: Accept-Encoding
复制代码
  • Age 资源在缓存代理中存贮的时长(取决于max-age和s-maxage的大小) 这个字段说的是资源在缓存服务器存在的时长,前面也说了Cache-Control: max-age=[秒]就是Age的最大值。 这个字段存在的意义是什么呢?用来区分请求的资源来自源服务器仍是缓存服务器的缓存的。 须要结合另外一个字段来进行判断,就是Date,Date是报文建立的时间。
Accept-Ranges: bytes
Age: 1016859
Cache-Control: max-age=2592000
Content-Length: 14119
Content-Type: image/png
Date: Fri, 01 Dec 2017 12:27:25 GMT
ETag: "5912bfd0-3727"
Expires: Tue, 19 Dec 2017 17:59:46 GMT
Last-Modified: Wed, 10 May 2017 07:22:56 GMT
Ohc-Response-Time: 1 0 0 0 0 0
Server: bfe/1.0.8.13-sslpool-patch
复制代码

咱们能够看到Age=1016859,说明这个资源已经在缓存服务器存在了1016859秒。若是文件被修改或替换,Age会从新由0开始累计。

Age消息头的值一般接近于0。表示此消息对象刚刚从原始服务器获取不久;其余的值则是表示代理服务器当前的系统时间与此应答消息中的通用消息头 Date的值之差。

静态资源Age + 静态资源Date = 原服务端Date
复制代码

6.Tcp的三次握手跟四次挥手是怎么回事?

TCP报文格式:

  • (1)32位序号:seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。
  • (2)确认序号:ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效,Ack=Seq+1。
  • (3)标志位:共6个,即URG、ACK、PSH、RST、SYN、FIN等,具体含义以下:(A)URG:紧急指针(urgent pointer)有效。(B)ACK:确认序号有效。(C)PSH:接收方应该尽快将这个报文交给应用层。(D)RST:重置链接。(E)SYN:发起一个新链接。(F)FIN:释放一个链接

**注意:**确认包的ack序号跟标志位的ACK不是指同一个,前者是ack序列号 ack=seq+1,后者是标志位的ack位,为1 时候表示确认序号有效。

三次握手

  • 第一次握手

客户端发送tcp请求包(标志位SYN为1,表示发起一个新链接。seq=x,初始序号x,保存在包头的序列号(Sequence Number)字段里)也成为ISN),客户端进入SYN-SENT阶段,而后服务器监听到请求连接,被动打开连接。

  • 第二次握手

服务端接受到客户端发送过来的tcp请求包以后,解析报文以后,服务器向客户端发回确认包(标志位ACK=1,表示确认序号有效。标志位SYN为1,表示发起一个新链接。ack=x+1,确认序号ack设置为x+1 便是第一次握手请求包里面的seq(ISN)加上1。而后确认包的序列号(seq)设置为y,返回给客户端)应答,服务端进入SYN-RCVD状态。

  • 第三次握手

客户端接受到服务端返回的确认包,解析报文,设置ack=ISN+1=y+1,seq=上一次返回的确认包的ack,而后发送确认包。

发送的确认包,标志位SYN为0,表示不用发起新链接,由于原先第一次握手已经创建了。标志位ACK为1,表示确认序号有效。确认包的确认序号ack=y+1,便是第二次握手确认包里面的序号seq加上1。这次握手返回的确认包 ,序列号(seq)设置为x+1,便是上一次确认包的ack确认序号,返回给服务端,进入ESTAB-LISHED状态,服务端收到以后,进入ESTAB-LISHED状态,双方连接创建,开始数据传送

SYN攻击

SYN攻击在三次握手过程当中,服务器发送SYN-ACK以后,收到客户端的ACK以前的TCP链接称为半链接(half-open connect).此时服务器处于Syn_RECV状态.当收到ACK后,服务器转入ESTABLISHED状态.

Syn攻击就是 攻击客户端 在短期内伪造大量不存在的IP地址,向服务器不断地发送syn包,服务器回复确认包,并等待客户的确认,因为源地址是不存在的,服务器须要不断的重发直 至超时,这些伪造的SYN包将长时间占用未链接队列,正常的SYN请求被丢弃,目标系统运行缓慢,严重者引发网络堵塞甚至系统瘫痪。

Syn攻击是一个典型的DDOS攻击。检测SYN攻击很是的方便,当你在服务器上看到大量的半链接状态时,特别是源IP地址是随机的,基本上能够判定这是一次SYN攻击.在Linux下能够以下命令检测是否被Syn攻击netstat -n -p TCP | grep SYN_RECV通常较新的TCP/IP协议栈都对这一过程进行修正来防范Syn攻击,修改tcp协议实现。主要方法有SynAttackProtect保护机制、SYN cookies技术、增长最大半链接和缩短超时时间等.可是不能彻底防范syn攻击。

四次挥手

TCP的链接的拆除须要发送四个包,所以称为四次挥手(four-way handshake)。客户端或服务器都可主动发起挥手动做,在socket编程中,任何一方执行close()操做便可产生挥手操做。

假设Client端发起中断链接请求,也就是发送FIN报文。

Server端接到FIN报文后,clinet的意思是"我Client端没有数据要发给你了,可是若是你还有数据没有发送完成,则没必要急着关闭Socket,能够继续发送数据。"

因此Server先发送ACK,告诉Client端,"你的请求我收到了,我知道你没东西传给我了,可是我这边还没准备好,请继续你等个人消息"。

这个时候Client端就进入FIN_WAIT状态,继续等待Server端的FIN报文。

此时Server有可能向client的传输数据还没结束,当Server端肯定数据已发送完成,则向Client端发送FIN报文,告诉Client端"好了,我这边数据发完了,准备好关闭链接了"。Client端收到FIN报文后,就知道能够关闭链接了,可是他仍是不相信网络,怕Server端不知道要关闭,因此发送ACK后进入TIME_WAIT状态,若是Server端没有收到ACK则会发起重传。

Server端收到ACK后,"就知道能够断开链接了"。Client端等待了2MSL(2个报文传送周期) 2个报文周期的计算:若是第四次握手的确认信息丢失,服务器将会从新发送第三次握手的断开链接的信号,而服务器发觉丢包(假设有确认信息的话要等待一个报文传输周期)与从新发送的断开链接到达主机的时间(一个报文传输周期)正好为 2 个报文传输周期。 2个报文传输周期以后依然没有收到回复,则证实Server端已正常关闭,那好,我Client端也能够关闭链接了。Ok,TCP链接就这样关闭了!

相关文章
相关标签/搜索