引用
建议阅读
HTTP协议
HTTP协议,即超文本传输协议(Hypertext transfer protocol),是一种详细规定了浏览器和万维网(WWW = World Wide Web)服务器之间互相通信的规则,通过因特网传送万维网文档的数据传送协议;它允许将超文本标记语言(HTML)文档从web服务器传送到客户端的浏览器。它是一个基于TCP/IP通信协议来传递数据,主要对应TCP/IP的应用层。
HTTP协议的主要特点:[1]
- 支持客户/服务器模式。
- 简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
- 灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
- 无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
- 无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
HTTP协议格式:[3]
-
请求报文
请求报文
客户端发送一个HTTP请求到服务器的请求消息由四个部分组成,分别是:请求行、请求头部、空行和请求数据。
-
请求行[1]
- 请求方法
请求行以一个方法符号开头,以空格分开,后面跟着请求的URI和协议的版本,格式如下:Method Request-URI HTTP-Version CRLF,其中 Method表示请求方法;Request-URI是一个统一资源标识符;HTTP-Version表示请求的HTTP协议版本,如:HTTP/1.1;CRLF表示回车和换行(除了作为结尾的CRLF外,不允许出现单独的CR或LF字符)。
请求方法如下:
- GET 请求获取Request-URI所标识的资源
- POST 在Request-URI所标识的资源后附加新的数据
- HEAD 请求获取由Request-URI所标识的资源的响应消息报头
- PUT 请求服务器存储一个资源,并用Request-URI作为其标识
- DELETE 请求服务器删除Request-URI所标识的资源
- TRACE 请求服务器回送收到的请求信息,主要用于测试或诊断
- OPTIONS 请求查询服务器的性能,或者查询与资源相关的选项和需求
- CONNECT 保留将来使用
- 请求方法
-
请求头部5
- Accept
- Accept: text/html 浏览器可以接受服务器回发的类型为 text/html。
- Accept: / 代表浏览器可以处理所有类型,(一般浏览器发给服务器都是发这个)。
- Accept-Encoding
- Accept-Encoding: gzip, deflate 浏览器申明自己接收的编码方法,通常指定压缩方法,是否支持压缩,支持什么压缩方法(gzip,deflate),(注意:这不是只字符编码)。
- Accept-Language
- Accept-Language:zh-CN,zh;q=0.9 浏览器申明自己接收的语言。
- Connection
- Connection: keep-alive 当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。
- Connection: close 代表一个Request完成后,客户端和服务器之间用于传输HTTP数据的TCP连接会关闭, 当客户端再次发送Request,需要重新建立TCP连接。
- Host(发送请求时,该报头域是必需的)
- Host:www.baidu.com 请求报头域主要用于指定被请求资源的Internet主机和端口号,它通常从HTTP URL中提取出来的。
- Referer
- Referer:https://www.baidu.com/?tn=62095104_8_oem_dg 当浏览器向web服务器发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的,服务器籍此可以获得一些信息用于处理。
- User-Agent
- User-Agent:Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36 告诉HTTP服务器, 客户端使用的操作系统和浏览器的名称和版本。
- Cache-Control
- Cache-Control:private 默认为private 响应只能够作为私有的缓存,不能再用户间共享
- Cache-Control:public 响应会被缓存,并且在多用户间共享。正常情况, 如果要求HTTP认证,响应会自动设置为 private
- Cache-Control:must-revalidate 响应在特定条件下会被重用,以满足接下来的请求,但是它必须到服务器端去验证它是不是仍然是最新的。
- Cache-Control:no-cache 响应不会被缓存,而是实时向服务器端请求资源。
- Cache-Control:max-age=10 设置缓存最大的有效时间,但是这个参数定义的是时间大小(比如:60)而不是确定的时间点。单位是[秒 seconds]。
- Cache-Control:no-store 在任何条件下,响应都不会被缓存,并且不会被写入到客户端的磁盘里,这也是基于安全考虑的某些敏感的响应才会使用这个。
- Cookie
- Cookie是用来存储一些用户信息以便让服务器辨别用户身份的(大多数需要登录的网站上面会比较常见),比如cookie会存储一些用户的用户名和密码,当用户登录后就会在客户端产生一个cookie来存储相关信息,这样浏览器通过读取cookie的信息去服务器上验证并通过后会判定你是合法用户,从而允许查看相应网页。当然cookie里面的数据不仅仅是上述范围,还有很多信息可以存储是cookie里面,比如sessionid等。
- Range(用于断点续传)
- Range:bytes=0-5 指定第一个字节的位置和最后一个字节的位置。用于告诉服务器自己想取对象的哪部分。
- Accept
-
HTTP协议版本6
版本发布过程:HTTP/0.9 -> HTTP/1.0 -> HTTP/1.1 -> HTTP/2-
HTTP/0.9
HTTP 0.9 是一个最古老的版本- 只支持GET请求方式:由于不支持其他请求方式,因此客户端是没办法向服务端传输太多的信息
- 没有请求头概念:所以不能在请求中指定版本号,服务端也只具有返回 HTML字符串的能力
- 服务端相响应之后,立即关闭TCP连接
-
HTTP/1.0
随着 HTTP 1.0 的发布,这个版本:- 请求方式新增了POST,DELETE,PUT,HEADER等方式
- 增添了请求头和响应头的概念,在通信中指定了 HTTP 协议版本号,以及其他的一些元信息 (比如: 状态码、权限、缓存、内容编码)
- 扩充了传输内容格式,图片、音视频资源、二进制等都可以进行传输
- 具有无状态无连接的特性
在这个版本主要的就是对请求和响应的元信息进行了扩展,客户端和服务端有更多的获取当前请求的所有信息,进而更好更快的处理请求相关内容。
-
HTTP/1.1
HTTP 1.1 是在 1.0 发布之后的半年就推出了,完善了 1.0 版本。目前也还有很多的互联网项目基于 HTTP 1.1 在向外提供服务,具有以下特性:- 长连接:新增Connection字段,可以设置keep-alive值保持连接不断开
HTTP 1.1默认保持长连接,数据传输完成保持tcp连接不断开,继续用这个通道传输数据。 - 管道化:基于上面长连接的基础,管道化可以不等第一个请求响应继续发送后面的请求,但响应的顺序还是按照请求的顺序返回。
- 缓存处理:新增字段cache-control
当浏览器请求资源时,先看是否有缓存的资源,如果有缓存,直接取,不会再发请求,如果没有缓存,则发送请求。 通过设置字段cache-control来控制缓存。 - 断点传输
在上传/下载资源时,如果资源过大,将其分割为多个部分,分别上传/下载,如果遇到网络故障,可以从已经上传/下载好的地方继续请求,不用从头开始,提高效率。
- 长连接:新增Connection字段,可以设置keep-alive值保持连接不断开
-
HTTP/2
HTTP/2主要特性:- 二进制分帧
HTTP 1.x 的解析是基于文本,HTTP 2之后将所有传输的信息分割为更小的消息和帧,并对它们采用二进制格式的编码,提高传输效率。 - 多路复用: 在共享TCP链接的基础上同时发送请求和响应
在共享TCP链接的基础上同时发送请求和响应,基于二进制分帧,在同一域名下所有访问都是从同一个tcp连接中走,http消息被分解为独立的帧,乱序发送,服务端根据标识符和首部将消息重新组装起来。。 - 头部压缩
由于 HTTP 是无状态的,每一个请求都需要头部信息标识这次请求相关信息,所以会造成传输很多重复的信息,当请求数量增大的时候,消耗的资源就会慢慢积累上去。所以 HTTP 2 可以维护一个头部信息字典,差量进行更新头信息,减少头部信息传输占用的资源,详见 HTTP/2 头部压缩技术介绍。 - 服务器推送:服务器可以额外的向客户端推送资源,而无需客户端明确的请求
- 二进制分帧
-
-
-
响应报文
响应报文
HTTP响应也由四个部分组成,分别是:响应行、响应头、空行、响应体。
-
状态以及状态描述
1xx(临时响应)
表示临时响应并需要请求者继续执行操作的状态代码。代码 说明 100 (继续) 请求者应当继续提出请求。 服务器返回此代码表示已收到请求的第一部分,正在等待其余部分。 101 (切换协议) 请求者已要求服务器切换协议,服务器已确认并准备切换。 2xx (成功)
表示成功处理了请求的状态代码。代码 说明 200 (成功) 服务器已成功处理了请求。 通常,这表示服务器提供了请求的网页。 201 (已创建) 请求成功并且服务器创建了新的资源。 202 (已接受) 服务器已接受请求,但尚未处理。 203 (非授权信息) 服务器已成功处理了请求,但返回的信息可能来自另一来源。 204 (无内容) 服务器成功处理了请求,但没有返回任何内容。 205 (重置内容) 服务器成功处理了请求,但没有返回任何内容。 206 (部分内容) 服务器成功处理了部分 GET 请求。 3xx (重定向)
表示要完成请求,需要进一步操作。 通常,这些状态代码用来重定向。代码 说明 300 (多种选择) 针对请求,服务器可执行多种操作。 服务器可根据请求者 (user agent) 选择一项操作,或提供操作列表供请求者选择。 301 (永久移动) 请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。 302 (临时移动) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。 303 (查看其他位置) 请求者应当对不同的位置使用单独的 GET 请求来检索响应时,服务器返回此代码。 304 (未修改) 自从上次请求后,请求的网页未修改过。 服务器返回此响应时,不会返回网页内容。 305 (使用代理) 请求者只能使用代理访问请求的网页。 如果服务器返回此响应,还表示请求者应使用代理。 307 (临时重定向) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。 4xx(请求错误)
这些状态代码表示请求可能出错,妨碍了服务器的处理。代码 说明 400 (错误请求) 服务器不理解请求的语法。 401 (未授权) 请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。 403 (禁止) 服务器拒绝请求。 404 (未找到) 服务器找不到请求的网页。 405 (方法禁用) 禁用请求中指定的方法。 406 (不接受) 无法使用请求的内容特性响应请求的网页。 407 (需要代理授权) 此状态代码与 401(未授权)类似,但指定请求者应当授权使用代理。 408 (请求超时) 服务器等候请求时发生超时。 409 (冲突) 服务器在完成请求时发生冲突。 服务器必须在响应中包含有关冲突的信息。 410 (已删除) 如果请求的资源已永久删除,服务器就会返回此响应。 411 (需要有效长度) 服务器不接受不含有效内容长度标头字段的请求。 412 (未满足前提条件) 服务器未满足请求者在请求中设置的其中一个前提条件。 413 (请求实体过大) 服务器无法处理请求,因为请求实体过大,超出服务器的处理能力。 414 (请求的 URI 过长) 请求的 URI(通常为网址)过长,服务器无法处理。 415 (不支持的媒体类型) 请求的格式不受请求页面的支持。 416 (请求范围不符合要求) 如果页面无法提供请求的范围,则服务器会返回此状态代码。 417 (未满足期望值) 服务器未满足”期望”请求标头字段的要求。 428 (要求先决条件) 先决条件是客户端发送 HTTP 请求时,如果想要请求能成功必须满足一些预设的条件。 429 (太多请求) 当你需要限制客户端请求某个服务数量时,该状态码就很有用,也就是请求速度限制。 431 (请求头字段太大) 客户端发送 HTTP 请求头过大。 5xx(服务器错误)
这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。代码 说明 500 (服务器内部错误) 服务器遇到错误,无法完成请求。 501 (尚未实施) 服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。 502 (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。 503 (服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。 504 (网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求。 505 (HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。 511 (要求网络认证) 客户端需要进行身份验证以获得网络访问权。 -
响应头5
- Cache-Control(对应请求中的Cache-Control)
- Cache-Control:private 默认为private 响应只能够作为私有的缓存,不能再用户间共享
- Cache-Control:public 浏览器和缓存服务器都可以缓存页面信息。
- Cache-Control:must-revalidate 对于客户机的每次请求,代理服务器必须想服务器验证缓存是否过时。
- Cache-Control:no-cache 浏览器和缓存服务器都不应该缓存页面信息。 - Cache-Control:max-age=10 是通知浏览器10秒之内不要烦我,自己从缓冲区中刷新。
- Cache-Control:no-store 请求和响应的信息都不应该被存储在对方的磁盘系统中。
- Content-Type
- Content-Type:text/html;charset=UTF-8 告诉客户端,资源文件的类型,还有字符编码,客户端通过utf-8对资源进行解码,然后对资源进行html解析。通常我们会看到有些网站是乱码的,往往就是服务器端没有返回正确的编码。
- Content-Encoding
- Content-Encoding:gzip 告诉客户端,服务端发送的资源是采用gzip编码的,客户端看到这个信息后,应该采用gzip对资源进行解码。 1. DateDate: Tue, 03 Apr 2018 03:52:28 GMT 这个是服务端发送资源时的服务器时间,GMT是格林尼治所在地的标准时间。http协议中发送的时间都是GMT的,这主要是解决在互联网上,不同时区在相互请求资源的时候,时间混乱问题。
- Server
- Server:Tengine/1.4.6 这个是服务器和相对应的版本,只是告诉客户端服务器信息。
- Transfer-Encoding
- Transfer-Encoding:chunked 这个响应头告诉客户端,服务器发送的资源的方式是分块发送的。一般分块发送的资源都是服务器动态生成的,在发送时还不知道发送资源的大小,所以采用分块发送,每一块都是独立的,独立的块都能标示自己的长度,最后一块是0长度的,当客户端读到这个0长度的块时,就可以确定资源已经传输完了。
- Expires
- Expires:Sun, 1 Jan 2000 01:00:00 GMT 这个响应头也是跟缓存有关的,告诉客户端在这个时间前,可以直接访问缓存副本,很显然这个值会存在问题,因为客户端和服务器的时间不一定会都是相同的,如果时间不同就会导致问题。所以这个响应头是没有Cache-Control:max-age=*这个响应头准确的,因为max-age=date中的date是个相对时间,不仅更好理解,也更准确。
- Last-Modified
- Last-Modified: Dec, 26 Dec 2015 17:30:00 GMT 所请求的对象的最后修改日期(按照 RFC 7231 中定义的“超文本传输协议日期”格式来表示)
- Connection
- Connection:keep-alive 这个字段作为回应客户端的Connection:keep-alive,告诉客户端服务器的tcp连接也是一个长连接,客户端可以继续使用这个tcp连接发送http请求。
- Etag
- ETag: "737060cd8c284d8af7ad3082f209582d" 就是一个对象(比如URL)的标志值,就一个对象而言,比如一个html文件,如果被修改了,其Etag也会别修改,所以,ETag的作用跟Last-Modified的作用差不多,主要供WEB服务器判断一个对象是否改变了。比如前一次请求某个html文件时,获得了其 ETag,当这次又请求这个文件时,浏览器就会把先前获得ETag值发送给WEB服务器,然后WEB服务器会把这个ETag跟该文件的当前ETag进行对比,然后就知道这个文件有没有改变了。
- Refresh
- Refresh: 5; url=http://baidu.com 用于重定向,或者当一个新的资源被创建时。默认会在5秒后刷新重定向。
- Access-Control-Allow-Origin
- Access-Control-Allow-Origin: * 号代表所有网站可以跨域资源共享,如果当前字段为那么
- Access-Control-Allow-Credentials就不能为true
- Access-Control-Allow-Origin: www.baidu.com 指定哪些网站可以跨域资源共享
- Access-Control-Allow-Methods
- Access-Control-Allow-Methods:GET,POST,PUT,DELETE 允许哪些方法来访问
- Access-Control-Allow-Credentials
- Access-Control-Allow-Credentials: true 是否允许发送cookie。默认情况下,Cookie不包括在CORS请求之中。设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。这个值也只能设为true,如果服务器不要浏览器发送Cookie,删除该字段即可。如果access-control-allow-origin为*,当前字段就不能为true
- Content-Range
- Content-Range: bytes 0-5/7877 指定整个实体中的一部分的插入位置,他也指示了整个实体的长度。在服务器向客户返回一个部分响应,它必须描述响应覆盖的范围和整个实体长度。
- Cache-Control(对应请求中的Cache-Control)
-
HTTP协议的请求流程:[2]
- 用户在浏览器中键入需要访问网页的URL或者点击某个网页中链接;
- 浏览器根据URL中的域名,通过DNS解析出目标网页的IP地址;
浏览器请求这个页面:http://hackr.ip/index.html
在这一步,需要域名系统DNS解析域名hackr.ip,得主机的IP地址20X.189.105.112。
然后将上面结合本机自己的信息,封装成一个http请求数据。 - 在HTTP开始工作前,客户端首先会通过TCP/IP协议来和服务端通过TCP三次握手建立链接;
- 建立连接后,客户机发送一个请求给服务器,请求方式的格式为:统一资源标识符(URL)、协议版本号,后边是MIME信息包括请求修饰符、客户机信息和内容;
- 服务器接到请求后,给予相应的响应信息,其格式为一个状态行,包括信息的协议版本号、一个成功或错误的代码,后边是MIME信息包括服务器信息、实体信息和可能的内容;
一般情况下,一旦Web服务器向浏览器发送了请求数据,它就要关闭TCP连接,然后如果浏览器或者服务器在其头信息加入了这行代码:
Connection:keep-alive,TCP连接在发送后将仍然保持打开状态,于是,浏览器可以继续通过相同的连接发送请求。保持连接节省了为每个请求建立新连接所需的时间,还节约了网络带宽。
一次请求流程
网友评论