HTTP协议特点

  1. HTTP(HyperText Transfer Protocol)协议,超文本传输协议是基于TCP的应用层协议,主要是用来规定客户端和服务端的数据传输格式,最初是用来向客户端传输HTML页面的内容,默认端口是80。
  2. HTTP协议是无状态的,每次HTTP请求都是独立的,任何两个请求之间没有什么必然的联系,但是实际应用中并不完全都是这样,引入了Cookie和Session机制来关联请求。
  3. 在客户端请求网页时多数情况下并不是一次请求就能成功的,服务端首先是响应HTML页面,然后浏览器收到响应之后发现HTML页面还引用了其他的资源,例如CSS,JS文件,图片等等,还会自动发送HTTP请求这些需要的资源。现在的HTTP版本支持管道机制,可以同时请求和响应多个请求,大大提高了效率。 4.HTTP协议目的是规定客户端和服务端数据传输的格式和数据交互行为,并不负责数据传输的细节。底层是基于TCP实现的。现在使用的版本中是默认持久连接的,也就是多次HTTP请求使用一个TCP连接。

HTTP报文

1.请求报文,报文由三个部分组成,即开始行、首部行和实体主体。在请求报文中,开始行就是请求行。请求报文就是由请求行、请求头、内容实体组成的,每一行的末尾都有回车和换行,在内容实体和请求头之间另有一个空行。其中请求行指定的是请求方法、请求URL、协议版本;请求头是键值对的形式存在的,就是字段名:值;内容实体就是要传输的数据。请求报文图如下: 请求报文

  1. 响应报文由状态行、响应首部字段(响应头)、响应实体组成,其中第一行是状态行,依次包含HTTP版本,状态码和状态短语组成;在一个回车换行之后是响应头,也是键值对的形式,字段名:值;然后会有一个空行也包含回车换行,之后是响应实体,就是要传输的数据。 响应报文

HTTP请求方法

请求方法是客户端用来告知服务器其动作意图的方法,就像下达命令一样,需要注意的是方法名区分大小写,需要使用大写字母。

  1. GET:获取资源,GET方法用来请求访问已被URI识别的资源,也就是指定了服务器处理请求之后响应的内容。
  2. POST:传输实体主体。POST与GET的区别之一就是目的不同,虽然GET方法也可以传输,但是一般不用,因为GET的目的是获取,POST的目的是传输。
  3. PUT:传输文件,类似FTP协议,文件内容包含在请求报文的实体中,然后请求保存到URL指定的服务器位置。
  4. HEAD:获得报文首部,类似GET方法,但是不同的是HEAD方法不要求返回数据。用于确认URI的有效性及资源更新时间等。
  5. DELETE:删除文件,是与PUT相反的方法,DELETE是要求返回URL指定的资源。
  6. OPTIONS:询问支持的方法,因为不是所有的服务器都支持规定的方法,为了安全有些服务器可能会禁止掉一些方法例如DELETE、PUT等,OPTIONS就是用来询问服务器支持的方法。
  7. TRACE:追踪路径,TRACE方法是让Web服务器将之前的请求通信环回给客户端的方法,这个方法并不常用。
  8. CONNECT:要求用隧道协议连接代理,CONNECT方法要求在与代理服务器通信时建立隧道,实现用隧道协议进行TCP通信。主要使用SSL/TLS协议对通信内容加密后传输。
    汇总:

HTTP的响应状态码

状态码是用来告知客户端服务器端处理请求的结果。凭借状态码用户可以知道服务器是请求处理成功、失败或者是被转发;这样出现了错误也好定位。状态码是由3位数字加原因短语组成。3位数字中的第一位是用来指定状态的类别。共有5种。

  1. 200:OK,代表请求被正常的处理成功了
  2. 204:No Content,请求处理成功,但是没有数据实体返回,也不允许有实体返回。比如说HEAD请求,可能就会返回204 No Content,因为HEAD就是只获取头信息。这里简单提一下205 Reset Content,和204 No Content的区别是不但没有数据实体返回,而且还需要重置表单,方便用户再次输入。
  3. 206:Partial Content,这是客户端使用Content-Range指定了需要的实体数据的范围,然后服务端处理请求成功之后返回用户需要的这一部分数据而不是全部,执行的请求就是GET。返回码就是206:Partial Content。
  4. 301:Moved Permanently,代表永久性定向。该状态码表示请求的资源已经被分配了新的URL,以后应该使用资源现在指定的URL。也就是说如果已经把资源对应的URL保存为书签了,这是应该按照Location首部字段提示的URL重新保存。
  5. 302:Found,代表临时重定向。该状态码表示请求的资源已经被分配了新的URL,但是和301的区别是302代表的不是永久性的移动,只是临时的。就是说这个URL还可能会发生改变。如果保存成书签了也不会更新。
  6. 303:See Other,和302的区别是303明确规定客户端应当使用GET方法。
  7. 304:Not Modified,该状态码表示客户端发送附带条件请求时,服务器端允许请求访问资源,但是没有满足条件。304状态码返回时不包含任何数据实体。304虽然被划分在3XX中但是和重定向没有关系。
  8. 307:Temporary Redirect,临时重定向,与302 Found相同,但是302会把POST改成GET,而307就不会。
  9. 400:Bad Request,400表示请求报文中存在语法错误。需要修改后再次发送。
  10. 401:Unauthorized,该状态码表示发送的请求需要有通过HTTP认证的认证信息。
  11. 403:Forbidden,表明请求访问的资源被拒绝了。没有获得服务器的访问权限,IP被禁止等。
  12. 404:Not Found,表明请求的资源在服务器上找不到。当然也可以在服务器拒绝请求且不想说明理由时使用。
  13. 408:Request Timeout表示客户端请求超时,就是在客户端和服务器建立连接后服务器在一定时间内没有收到客户端的请求。
  14. 500:Internal Server Error,表明服务器端在执行请求时发生了错误,很有可能是服务端程序的Bug或者临时故障。
  15. 503:Service Unavailable,表明服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。如果事先得知解除以上状况需要的时间,最好写入Retry-After字段再返回给客户端。
  16. 504:Getaway Timeout,网关超时,是代理服务器等待应用服务器响应时的超时,和408 Request Timeout的却别就是504是服务器的原因而不是客户端的原因

HTTP首部字段

  1. HTTP首部字段是构成HTTP报文最重要的元素之一。在客户端与服务端之前进行信息传递的时候请求和响应都会使用首部字段,会传递一些重要的元信息。首部字段是以键值对的形式存在的。包含报文的主体大小、语言、认证信息等。HTTP首部字段包含4种类型。
  2. 通用首部字段:代表请求报文和响应报文都会使用的字段
    请求首部字段:是客户端向服务端发送请求时使用的首部字段。包含请求的附加内容、客户端信息、响应内容相关优先级等信息。 响应首部字段:是服务端向客户端返回响应时使用的首部字段,包含响应的附加内容,可能也会要求客户端附加额外的内容信息。 实体首部字段:是针对请求报文和响应报文的实体部分使用的首部。包含资源内容更新时间等和实体有关的信息。

HTTP常见问题

  1. GET和POST的区别
    A. 从字面意思和HTTP的规范来看,GET用于获取资源信息而POST是用来更新资源信息。
    B. GET提交请求的数据实体会放在URL的后面,用?来分割,参数用&连接,举个栗子:/index.html?name=wang&login=1
    C. GET提交的数据长度是有限制的,因为URL长度有限制,具体的长度限制视浏览器而定。而POST没有。
    D. GET提交的数据不安全,因为参数都会暴露在URL上。
  2. 408 Request Timeout和504 Gateway Timeout的区别
    408是说请求超时,就是建立连接之后再约定的时间内客户端没有发送请求到客户端到服务端。本质上原因在于客户端或者网络拥塞。504是网关超时,是说代理服务器把客户端请求转发到应用服务器后再约定的时间内没有收到应用服务器的响应。本质上原因在于服务端的响应过慢,也有可能是网络问题。
  3. Cookie和Session的区别和联系
    Cookie和Session都是为了保存客户端和服务端之间的交互状态,实现机制不同,各有优缺点。首先一个最大的区别就是Cookie是保存在客户端而Session就保存在服务端的。Cookie是客户端请求服务端时服务器会将一些信息以键值对的形式返回给客户端,保存在浏览器中,交互的时候可以加上这些Cookie值。用Cookie就可以方便的做一些缓存。Cookie的缺点是大小和数量都有限制;Cookie是存在客户端的可能被禁用、删除、篡改,是不安全的;Cookie如果很大,每次要请求都要带上,这样就影响了传输效率。Session是基于Cookie来实现的,不同的是Session本身存在于服务端,但是每次传输的时候不会传输数据,只是把代表一个客户端的唯一ID(通常是JSESSIONID)写在客户端的Cookie中,这样每次传输这个ID就可以了。Session的优势就是传输数据量小,比较安全。但是Session也有缺点,就是如果Session不做特殊的处理容易失效、过期、丢失或者Session过多导致服务器内存溢出,并且要实现一个稳定可用安全的分布式Session框架也是有一定复杂度的。在实际使用中就要结合Cookie和Session的优缺点针对不同的问题来设计解决方案。

HTTP1.0和HTTP1.1的区别

  1. 缓存处理,在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。
  2. 带宽优化及网络连接的使用,HTTP1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP1.1则在请求头引入了range头域,它允许只请求资源的某个部分,即返回码是206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接。
  3. 错误通知的管理,在HTTP1.1中新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。
  4. Host头处理,在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。HTTP1.1的请求消息和响应消息都应支持Host头域,且请求消息中如果没有Host头域会报告一个错误(400 Bad Request)。
  5. 长连接,HTTP 1.1支持长连接(PersistentConnection)和请求的流水线(Pipelining)处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,在HTTP1.1中默认开启Connection: keep-alive,一定程度上弥补了HTTP1.0每次请求都要创建连接的缺点。

HTTP2.0和HTTP1.X相比的新特性

  1. 新的二进制格式(Binary Format),HTTP1.x的解析是基于文本。基于文本协议的格式解析存在天然缺陷,文本的表现形式有多样性,要做到健壮性考虑的场景必然很多,二进制则不同,只认0和1的组合。基于这种考虑HTTP2.0的协议解析决定采用二进制格式,实现方便且健壮。
  2. 多路复用(MultiPlexing),即连接共享,即每一个request都是是用作连接共享机制的。一个request对应一个id,这样一个连接上可以有多个request,每个连接的request可以随机的混杂在一起,接收方可以根据request的 id将request再归属到各自不同的服务端请求里面。
  3. header压缩,如上文中所言,对前面提到过HTTP1.x的header带有大量信息,而且每次都要重复发送,HTTP2.0使用encoder来减少需要传输的header大小,通讯双方各自cache一份header fields表,既避免了重复header的传输,又减小了需要传输的大小。
  4. 服务端推送(server push)

HTTP2.0多路复用与HTTP1.X中的长连接复用区别

  1. HTTP/1.* 一次请求-响应,建立一个连接,用完关闭;每一个请求都要建立一个连接
  2. HTTP/1.1 Pipeling解决方式为,若干个请求排队串行化单线程处理,后面的请求等待前面请求的返回才能获得执行机会,一旦有某请求超时等,后续请求只能被阻塞,毫无办法,也就是人们常说的线头阻塞
  3. HTTP/2多个请求可同时在一个连接上并行执行。某个请求任务耗时严重,不会影响到其它连接的正常执行
  4. HTTP 性能优化的关键并不在于高带宽,而是低延迟。TCP 连接会随着时间进行自我「调谐」,起初会限制连接的最大速度,如果数据成功传输,会随着时间的推移提高传输的速度。这种调谐则被称为 TCP 慢启动。由于这种原因,让原本就具有突发性和短时性的 HTTP 连接变的十分低效。 HTTP/2 通过让所有数据流共用同一个连接,可以更有效地使用 TCP 连接,让高带宽也能真正的服务于 HTTP 的性能提升。

HTTP的连接过程

  1. 域名解析(DNS)
  2. 发起TCP的3次握手
  3. Web浏览器向Web服务器发送http请求命令,一旦建立了TCP连接,Web浏览器就会向Web服务器发送请求命令。例如:GET/sample/hello.jsp HTTP/1.1
  4. Web浏览器发送http请求头信息
  5. Web服务器应答,客户机向服务器发出请求后,服务器会客户机回送应答,HTTP/1.1 200 OK,应答的第一部分是协议的版本号和应答状态码
  6. Web服务器向浏览器发送数据,Web服务器向浏览器发送头信息后,它会发送一个空白行来表示头信息的发送到此为结束,接着,它就以Content-Type应答头信息所描述的格式发送用户所请求的实际数据
  7. Web服务器关闭TCP连接,一般情况下,一旦Web服务器向浏览器发送了请求数据,它就要关闭TCP连接,然后如果浏览器或者服务器在其头信息加入了这行代码:connection:keep-aliveTCP连接在发送后将仍然保持打开状态,于是,浏览器可以继续通过相同的连接发送请求。保持连接节省了为每个请求建立新连接所需的时间,还节约了网络带宽。
  8. 当我们在浏览器的地址栏输入 www.baidu.com ,然后回车,回车这一瞬间到看到页面到底发生了什么呢?
    域名解析 –> 发起TCP的3次握手 –> 建立TCP连接后发起http请求 –> 服务器响应http请求,浏览器得到html代码 –> 浏览器解析html代码,并请求html代码中的资源(如js、css、图片等) –> 浏览器对页面进行渲染呈现给用户