@TOC
HTTP的诞生
1989 年 3 月 CERN(欧洲核子研究组织) 的蒂姆 • 伯纳斯 - 李(Tim BernersLee)博士提出了一种能让远隔两地的研究者们共享知识的设想,蒂姆 • 伯纳斯 - 李也成为万维网之父。
一、HTTP介绍
http简称超文本传输协议,属于应用层协议,基本用于应用之间的数据传输,常用于web方向,是基于tcp的应用层协议,有时候还会基于ssl,tsl就是我们说的https协议
HTTP协议(超文本传输协议HyperText Transfer Protocol),它是基于TCP协议的应用层传输协议,简单来说就是客户端和服务端进行数据传输的一种规则。
注意:客户端与服务器的角色不是固定的,一端充当客户端,也可能在某次请求中充当服务器。这取决与请求的发起端。HTTP协议属于应用层,建立在传输层协议TCP之上。客户端通过与服务器建立TCP连接,之后发送HTTP请求与接收HTTP响应都是通过访问Socket接口来调用TCP协议实现。
没有人能够全面掌握互联网中的传输状况
二、HTTP的组成
http属于一个文本协议,通过客户端和服务器之间的规则来实现特定的效果
1. HTTP组成报文格式及实例
请求报文格式
下面是自制服务器,使用谷歌浏览器发送请求的报文(以公开,可访问)
具体内容:
GET /favicon.ico HTTP/1.1
Host: 121.40.62.167:9999
Connection: keep-alive
User-Agent: Mozilla/5.0 (windows NT 10.0: Win64: x64) Applewebkit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.114 safari/537.36 Edg/103.0.1264 .49
Accept: image/webp, image/apng, image/svg+xml, image/*, */*;q=0.8Referer: http://xxxxxxx:9999/Accept-Encoding: gzip, deflate
Accept-Language: zh-CN, zh:q=0.9, en: q=0.8, en-GB;q=0.7, en-US;q=0.6
Cookie: order=id20desc; serverType=nginx: pro_end=-1: 1td_end=-1: memsize=3748; bt_user_info=87B822status2283Atrue82C22msg2283A8228u83B78u5 3D68u6210%u529F82182282C22data223A87B822username 223A822183****78392287D87D: backup_path=/www/backup: sites_path=/www/wwwroot; site_model=ava: config-tab=1: 9273e354ba8b7935dcc533ebc06536a1=ab3ce455-9457-49d4-b89c-2c04cc01b71c.xR1YyxrEwTAUYzvxseaocd07_Us; request_token=KMakqkKidow7YyDmGylvP57BXkPCOAWIpoQnp302zq6RX6wD: network-unitType=KB/s; disk-unitType=MB/s; controlType=control
If-Modified-since: Wed, 22 Jul-2009 19:15:56 GMT
响应报文格式
HTTP/1.1 200 OK
Date: Mon, 27 Jul 2009 12:28:53 GMT
Server: Apache/2.2.14 (Win32)
Last-Modified: Wed, 22 Jul 2009 19:15:56 GMT
Content-Length: 88
Content-Type: text/html
Connection: Closed\n
Hello
URL和URI
统一资源定位符(Uniform Resource Locator,URL),统一资源名称(Uniform Resource
Name,URN)是URI的子集。 Web上地址的基本形式是URI, 它有两种形式:
1.一种是URL,这是目前URI的最普遍形式。
2.一种就是URN,这是URL的一种更新形式,URN不依赖于位置,并且有可能减少失效连接的个数。但是其流行还需假以时日,因为它需要更精密软件的支持。
URI的格式如下:
1.协议:该http的协议为“http:”,这代表网页使用的是HTTP协议。在Internet中可以使用多种协议。在"HTTP"后面的“//”为分隔符
2.域名:该URL的域名部分为“www.aspxfans.com”。一个URL中,也可以使用IP地址作为域名使用
3.端口:跟在域名后面的是端口,域名和端口之间使用“:”作为分隔符。端口不是一个URL必须的部分,如果省略端口部分,将采用默认端口 http为80,https为443
4.路径:从域名后的第一个“/”开始到最后一个“?”,不是一个URL必须的部分
5.片段部分:从“#”开始到最后,都是锚部分”。不是一个URL必须的部分
6.参数部分:从“?”开始到“#”为止之间的部分为参数部分,又称搜索部分、查询部分。本例中的参数部分为“query = 1”。参数可以允许有多个参数,参数与参数之间用“&”作为分隔符,不是一个URL必须的部分
2.HTTP的请求方法
根据 HTTP 标准,HTTP 请求可以使用多种请求方法。
HTTP1.0 定义了三种请求方法: GET, POST 和 HEAD 方法。
HTTP1.1 新增了六种请求方法:OPTIONS、PUT、PATCH、DELETE、TRACE 和 CONNECT 方法。
序号 方法 描述 1 GET 请求指定的页面信息,并返回实体主体。
2 HEAD 类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头
3 POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。
4 PUT 从客户端向服务器传送的数据取代指定的文档的内容。 5 DELETE 请求服务器删除指定的页面。
6 CONNECT HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。 7 OPTIONS 允许客户端查看服务器的性能。
8 TRACE 回显服务器收到的请求,主要用于测试或诊断。 9 PATCH 实体中包含一个表,表中说明与该URI所表示的原内容的区别。
10 MOVE 请求服务器将指定的页面移至另一个网络地址。 11 COPY 请求服务器将指定的页面拷贝至另一个网络地址。
12 LINK 请求服务器建立链接关系。 13 UNLINK 断开链接关系。 14 WRAPPED 允许客户端发送经过封装的请求。
15 Extension-mothed 在不改动协议的前提下,可增加另外的方法。
例如:
POST /favicon.ico HTTP/1.1
Host: hosts
Connection: keep-alive
User-Agent: Mozilla/5.0 (windows NT 10.0: Win64: x64) Applewebkit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.114 safari/537.36 Edg/103.0.1264 .49
Accept: image/webp, image/apng, image/svg+xml, image/, /*;q=0.8Referer: http://xxxxxxx:9999/Accept-En... gzip, deflate
Accept-Language: zh-CN, zh:q=0.9, en: q=0.8, en-GB;q=0.7, en-US;q=0.6
三、HTTP的版本
http1.1中文版介绍 https://www.cnblogs.com/Kimbi...
HTTP1.1特点
持久连接节省通信量
HTTP 1.0 : 规定浏览器与服务器只保持短暂的连接,浏览器的每次请求都需要与服务器建立一个 TCP 连接,服务器完成请求处理后立即断开 TCP 连接,服务器不跟踪每个客户也不记录过去的请求。
协议规定HTTP/1.0如果想要保持长连接,需要在请求头中加上Connection:
keep-alive,但是很多游览器加上的也达不到长链接的效果httpclient使用HTTP/1.0协议去请求tomcat时,即使带上Connection: keep-alive请求头也保持不了长连接
而HTTP/1.1默认是支持长连接的,有没有这个请求头都行。
当然了,协议是这样规定的,至于支不支持还得看服务器(比如tomcat)和客户端(比如浏览器)的具体实现。在实践过程中发现谷歌浏览器使用HTTP/1.1协议时请求头中总会带上Connection: keep-alive,另外通过。如果HTTP/1.1版本的http请求报文不希望使用长连接,则要在请求头中加上Connection: closed,接收到这个请求头的对端服务就会主动关闭连接。
http长连接也不会一直保持,一般服务端都会设置keep-alive超时时间。超过指定的时间间隔,服务端就会主动关闭连接。同时服务端还会设置一个参数叫最大请求数,比如当最大请求数是300时,只要请求次数超过300次,即使还没到超时时间,服务端也会主动关闭连接。
持久连接的特点是,只要任意一端没有明确提出断开连接,则保持TCP连接状态。
管道化( Pipelining)
HTTP Pipelining是这样一种技术:在等待上一个请求响应的同时,发送下一个请求
HTTP Pipelining其实是把多个HTTP请求放到一个TCP连接中一一发送,而在发送过程中不需要等待服务器对前一个请求的响应;只不过,客户端还是要按照发送请求的顺序来接收响应。这也是大多数浏览器会关闭这个技术的原因
Host 头处理:
支持 Host 头域,不在以 IP 为请求方标志
HTTP 1.0 :中认为每台服务器都绑定一个唯一的 IP 地址,因此,请求消息中的 URL 并没有传递主机名。但随着虚拟主机技术的发展,一台服务器上可以存在多个虚拟主机,共享一个 IP 地址。
HTTP 1.1 :的请求消息和响应消息都应支持 Host 头域,且请求消息中如果没有 Host 头域会报告一个错误(400 Bad Request )
缓存处理
当缓存有效的时候,我们肯定希望从缓存中获得数据,那怎么判断缓存是否有效呢?这就是接下来需要讨论的问题——新鲜度检测。与之相关的是两个很重要的头部,Expires和Cache-control:max-age,其中Expires来自http/1.0+,Cache-Control来自http/1.1。其中Cache-Control:max-age定义了文档的使用期,是一个相对时间,如Cache-Control:max-age=3600,单位为秒;Expires指定的是一个绝对时间。很明显相对时间比绝对时间靠谱多了。因为绝对时间是依赖于计算机时钟的设定的。但是很多时候两者都被设定了,主要原因是有些客户端不支持http/1.1,无法识别Cache-Control,这是一种兼容策略。当然,Expires和Cache-control同时存在的时候,Cache-Control的优先级是高于Expires的。
错误状态码的增多
http1.1新增了24个错误状态响应码,丰富的错误码更加明确各个状态
HTTP 1.1 中新增了24个错误状态响应码,如 409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。
HTTP2.0
(2).HTTP2.0和HTTP1.X相比的新特性
新的二进制格式(Binary Format),HTTP1.x的解析是基于文本。基于文本协议的格式解析存在天然缺陷,文本的表现形式有多样性,要做到健壮性考虑的场景必然很多,二进制则不同,只认0和1的组合。基于这种考虑HTTP2.0的协议解析决定采用二进制格式,实现方便且健壮。
多路复用(MultiPlexing),即连接共享,即每一个request都是是用作连接共享机制的。一个request对应一个id,这样一个连接上可以有多个request,每个连接的request可以随机的混杂在一起,接收方可以根据request的 id将request再归属到各自不同的服务端请求里面。
header压缩,如上文中所言,对前面提到过HTTP1.x的header带有大量信息,而且每次都要重复发送,HTTP2.0使用encoder来减少需要传输的header大小,通讯双方各自cache一份header fields表,既避免了重复header的传输,又减小了需要传输的大小。
服务端推送(server push),同SPDY一样,HTTP2.0也具有server push功能。
二进制分帧
HTTP/2 采用二进制格式传输数据,而非 HTTP 1.x 的文本格式,二进制协议解析起来更高效。 HTTP / 1 的请求和响应报文,都是由起始行,首部和实体正文(可选)组成,各部分之间以文本换行符分隔。HTTP/2 将请求和响应数据分割为更小的帧,并且它们采用二进制编码。虽然HTTP1.1 的纯文本形式看起来一目了然,非常直观,但这只是对人的体验而言,事实上这种方式存在多义性,例如大小写、空白字符、回车换行、多字少字等,程序在处理的时候需要复杂的处理。效率比较低且麻烦,而二进制的方式,只是0和1,可以严格规定字段大小,顺序,标志位等,不存在歧义,提交小,同时也提升了数据在网络中传输的效率。
头部压缩
HTTP 1.1请求的大小变得越来越大,有时甚至会大于TCP窗口的初始大小,因为它们需要等待带着ACK的响应回来以后才能继续被发送。Gzip只会对请求体进行压缩,现在HTTP 2.0 提供了首部压缩方案。现在SPDY和HTTP 2.0都支持首部压缩,前者使用的是DEFLATE算法,而后者使用专门设计的HPACK算法进行压缩传输,能够节省消息头占用的网络的流量。
想要深入直接跳转:http://www.blogjava.net/yongb...
帧头为固定的9个字节((24+8+8+1+31)/8=9)呈现,变化的为帧的负载(payload),负载内容是由帧类型(Type)定义。
帧长度Length:无符号的自然数,24个比特表示,仅表示帧负载所占用字节数,不包括帧头所占用的9个字节。默认大小区间为为0~16,384(2^14),一旦超过默认最大值2^14(16384),发送方将不再允许发送,除非接收到接收方定义的SETTINGS_MAX_FRAME_SIZE(一般此值区间为2^14 ~ 2^24)值的通知。
帧类型Type:8个比特表示,定义了帧负载的具体格式和帧的语义,HTTP/2规范定义了10个帧类型,这里不包括实验类型帧和扩展类型帧
帧的标志位Flags:8个比特表示,服务于具体帧类型,默认值为0x0。有一个小技巧需要注意,一般来讲,8个比特可以容纳8个不同的标志,比如,PADDED值为0x8,二进制表示为00001000;END_HEADERS值为0x4,二进制表示为00000100;END_STREAM值为0X1,二进制为00000001。可以同时在一个字节中传达三种标志位,二进制表示为00001101,即0x13。因此,后面的帧结构中,标志位一般会使用8个比特表示,若某位不确定,使用问号?替代,表示此处可能会被设置标志位
帧保留比特为R:在HTTP/2语境下为保留的比特位,固定值为0X0
流标识符Stream Identifier:无符号的31比特表示无符号自然数。0x0值表示为帧仅作用于连接,不隶属于单独的流。
报文头压缩和解压
和HTTP/1一样,HTTP/2报头字段包含一个或多个相关的键值对。报头字段会在HTTP请求/响应报头和服务器推送操作中使用。原先为文本字段,现在需要使用HTTP报头压缩进行序列化成报头分块,作为HEADERS 、 PUSH_PROMISE、CONTINUATION等帧的负载传输出去。
解压缩采用的HPACK协议,具体可参考:http://http2.github.com/http2...
接收端合并接收到的帧组装成报头分块,解压缩还原报头集合。
一个完整的报头分块包含: - 单个包含报头终止标记END_HEADERS的HEADERS、PUSH_PROMISE帧,或者 - HEADERS、PUSH_PROMISE帧不包含的END_HEADERS标记,后续跟随一个或多个CONTINUATION帧,最后一个CONTINUATION帧包含了END_HEADERS标记。
报头压缩是有状态的,在一个完整的连接中,一方的压缩上下文环境,另一方的解压的上下文环境,都是需要具备的。报头解码失败需要作为连接错误COMPRESSION_ERROR对待。
HTTP2 的帧类型
| Frame Type | Code |
|--|--|
|HEADERS | 0x1 |
|PRIORITY| 0x2|
|RST_STREAM |0x3|
|SETTINGS| 0x4
|PUSH_PROMISE| 0x5 |
|PING |0x6 |
|GOAWAY| 0x7 |
|WINDOW_UPDATE| 0x8 |
|CONTINUATION| 0x9 |
例如 HEADER
报头主要载体,请求头或响应头,同时呢也用于打开一个流,在流处于打开"open"或者远程半关闭"half closed (remote)"状态都可以发送。
字段列表: - Pad Length:受制于PADDED标志控制是否显示,8个比特表示填充的字节数。 - E:一个比特表示流依赖是否专用,可选项,只在流优先级PRIORITY被设置时有效 - Stream Dependency:31个比特表示流依赖,只在流优先级PRIORITY被设置时有效 Weight:8个比特(一个字节)表示无符号的自然数流优先级,值范围自然是(1~256),或称之为权重。只在流优先级PRIORITY被设置时有效 - Header Block Fragment:报头块分片 - Padding:填充的字节,受制于PADDED标志控制是否显示,长度由Pad Length字段决定
所需标志位: END_STREAM (0x1): 报头块为最后一个,意味着流的结束。后续可紧接着CONTINUATION帧在当前的流中,需要把CONTINUATION帧作为HEADERS帧的一部分对待 END_HEADERS (0x4): 此报头帧不需分片,完整的一个帧。后续不再需要CONTINUATION帧帮忙凑齐。若没有此标志的HEADER帧,后续帧必须是以CONTINUATION帧传递在当前的流中,否则接收者需要响应PROTOCOL_ERROR类型的连接错误。 PADDED (0x8): 需要填充的标志 PRIORITY (0x20): 优先级标志位,控制独立标志位E,流依赖,和流权重。
注意事项: - 其负载为报头块分片,若内容过大,需要借助于CONTINUATION帧继续传输。若流标识符为0x0,结束段需要返回PROTOCOL_ERROR连接异常。HEADERS帧包含优先级信息是为了避免潜在的不同流之间优先级顺序的干扰。 - 其实一般来讲,报文头部不大的情况下,一个HEADERS就可以完成了,特殊情况就是Cookie字段超过16KiB大小,不常见。
多路复用
HTTP 1.0的模式是,建立连接请求数据完毕之后就立即关闭连接;后来采用了keep-alive保活模式使得可以复用连接不断开,可以利用这次连接继续请求数据。但是始终会有一个缺点,就是你必须等待服务器返回上一次的请求数据你才可以进行下一次的请求。
万一我们遇到有一个请求很久都不返回数据,那后面的请求只能继续等待。如何解决这个问题呢?HTTP 2.0就提出了多路复用的技术,就是你可以连续发送多个请求,可以不用收到回复就继续发送请求。
并行交错发送请求,请求之间互不影响
TCP连接一旦建立可以并行发送请求
消除不必要延迟,减少页面加载时间
可以最大程度利用HTTP 1.xIO 多路复用是一种同步IO模型,实现一个线程可以监视多个文件句柄;
一旦某个文件句柄就绪,就能够通知应用程序进行相应的读写操作;
没有文件句柄就绪就会阻塞应用程序,交出CPU。
服务器推送
HTTP2中服务端可以在发送页面HTML时主动推送其它资源,而不用等到浏览器解析到相应位置,发起请求再响应。
例如服务端可以主动把JS和CSS等一些静态主动推送给客户端,而不需要客户端解析HTML时再发送这些请求。
这样可以大大节省服务器之间的交互,如果一次性推送了太多的资源,因为浏览器需要处理所有推送过来的资源。反而会拖累性能。所以需要根据业务场景做权衡。
四.HTTP和HTTPS区别
HTTP既是超文本传输协议,用于从网络传输超文本数据到本地浏览器的协议。HTTPS是以安全为目标的HTTP通道,在其基础上加入了证书机制进行加密。区别在于,一个有证书加密一个没有证书,在安全上具有差异;端口上也不同,HTTP是80端口,HTTP是443端口。
HTTP 默认工作在 TCP 协议 80 端口,用户访问网站 http:// 打头的都是标准 HTTP 服务。
HTTP 协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息,因此,HTTP协议不适合传输一些敏感信息,比如:信用卡号、密码等支付信息。
HTTPS(Hypertext Transfer Protocol Secure:超文本传输安全协议)是一种透过计算机网络进行安全通信的传输协议。HTTPS 经由 HTTP 进行通信,但利用 SSL/TLS 来加密数据包。HTTPS 开发的主要目的,是提供对网站服务器的身份认证,保护交换数据的隐私与完整性。
HTTPS 默认工作在 TCP 协议443端口,它的工作流程一般如以下方式:
1、TCP 三次同步握手
2、客户端验证服务器数字证书
3、DH 算法协商对称加密算法的密钥、hash 算法的密钥
4、SSL安全加密隧道协商完成
5、网页以加密的方式传输,用协商的对称加密算法和密钥加密,保证数据机密性;用协商的hash算法进行数据完整性保护,保证数据不被篡改。
HTTP 明文传输,数据都是未加密的,安全性较差,HTTPS(SSL+HTTP) 数据传输过程是加密的,安全性较好。
使用 HTTPS 协议需要到 CA(Certificate Authority,数字证书认证机构) 申请证书,一般免费证书较少,因而需要一定费用。证书颁发机构如:Symantec、Comodo、GoDaddy 和 GlobalSign 等。
HTTP 页面响应速度比 HTTPS 快,主要是因为 HTTP 使用 TCP 三次握手建立连接,客户端和服务器需要交换 3 个包,而 HTTPS除了 TCP 的三个包,还要加上 ssl 握手需要的 9 个包,所以一共是 12 个包。
http 和 https 使用的是完全不同的连接方式,用的端口也不一样,前者是 80,后者是 443。
HTTPS 其实就是建构在 SSL/TLS 之上的 HTTP 协议,所以,要比较 HTTPS 比 HTTP 要更耗费服务器资源。
与HTTP关系密切的协议:IP、TCP和DNS
ip
ip就是互联网中,每一个网络的唯一标识,其中根据ip段,网络结构区分为外网ip和内网ip,局域网
IP协议的作用是把各种数据包传送给对方。而要保证确实传送到对方那里,则需要满足各类条件。
ARP
地址解析协议,即ARP(Address Resolution Protocol),是根据IP地址获取物理地址的一个TCP/IP协议。主机发送信息时将包含目标IP地址的ARP请求广播到网络上的所有主机,并接收返回消息,以此确定目标的物理地址
使用ARP协议凭借MAC地址进行通信
发送端首先发送一个带SYN标志的数据包给对方。接收端收到后,回传一个带有SYN/ACK标志的数据包以示传达确认信息。最后,发送端再回传一个带ACK标志的数据包,代表“握手”结束。
DNS
负责域名解析的DNS服务
DNS(Domain Name System)服务是和HTTP协议一样位于应用层的协议。它提供域名到IP地址之间的解析服务。
总结
HTTP1.1
持久连接 请求管道化
增加缓存处理(新的字段如cache-control)
增加Host字段、
支持断点传输等
HTTP2.0
二进制分帧
多路复用
头部压缩
服务器推送
参考:
百度百科
百度图片(直接搜来就用)
HTTP请求方法对照表
http1.1缓存
http2.0
图解HTTP
http2.0栈帧