HTTP协议是计算机网络中两台计算机通信所必须遵守的规定或规则,是一种通信协议,它允许将HTML从服务器传送到客户端的浏览器。
特点
- 支持客户/服务器模式
- 简单快速,发送请求时只需要传递请求方法和路径
- 灵活,可以传输任意类型的数据对象
- 无连接,每次连接只处理一个请求(即短连接,但HTTP1.1支持长连接)
- 无状态,不会对请求或者响应信息进行保存。
HTTP报文
请求报文
- 请求行:请求方法、请求路径、HTTP协议版本
- 请求头
- 请求主体
响应报文
- 状态行:HTTP协议版本、状态码、状态描述
- 响应头
- 响应主体
头信息和主体信息之间有一个空行。
HTTP目前一般常用的是HTTP1.1协议。
常用的请求方法:
- GET:主要用来请求访问已被URI标识的资源。
- HEAD:主要用来获取报文头部,它和GET方法一样,但是HEAD方法不返回主体部分,可以用来确认URI的有效性或者是资源的更新日期。
- POST:用来通过请求实体向服务器提交数据
- OPTIONS:返回服务器支持的请求方法。
GET和POST方法的区别
- GET传送数据量较小,不能大于2KB。
- GET参数通过URL传递,POST放在Request body中。
- GET安全性比POST要差
- GET产生一个TCP数据包;POST产生两个TCP数据包。
对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
状态码和状态描述
-
2XX:成功
- 204:No Content 没有内容,表示服务器成功处理请求,但返回中不包含主体信息
- 206:Partial Content 部分内容,客户端进行了范围请求,服务器成功执行该GET请求,响应报文中包含Content-Range指定返回的主体内容。
-
3XX:重定向
-
301:Moved Permanently 永久重定向
- 302:Found 临时重定向
-
304:Not Modified 资源未修改
- 307:Temporary Redirect 重定向中保持原有的请求数据(比如post请求页面a,页面重定向到b,使用307可以将post的数据转到b页面中)
-
4XX:客户端错误
-
400:Bad Request 请求报文中存在语法错误
- 401:Unauthorized 表示发送请求需要有通过HTTP认证的认证信息
- 403:Forbidden 请求资源的访问被服务器拒绝
-
404:Not found 请求的网页或资源不存在
- 405:Method Not Allowed 请求方法不被允许
-
5XX:服务端错误
- 500:Internal Server Error 服务器内部错误
- 503:Service Unavailable 服务器暂时不可用
头部字段
请求和响应都需要头部字段,它起到传递额外重要信息的作用。
请求头部字段
-
Host:www.baidu.com 客户端想请求的域名,由于一个ip下会有多个虚拟主机和域名,所以要指定域名
-
Accept:text/html 客户端能处理的媒体类型
-
Accept-Charset:iso-8859-5 客户端能支持的字符集
-
Accept-Encoding:gzip 客户端能支持的内容(压缩)编码
-
Accept-Language:zh-cn,zh 客户端能处理的自然语言
-
Authorization:客户端发送给服务端的认证信息
-
Proxy-Authorization:客户端发送给代理的认证信息
-
Range:bytes = 5001 - 10000 只获得部分资源的范围请求时,客户端告诉服务器资源的指定范围
-
User-Agent:创建请求的浏览器或用户代理的名称等信息
-
Referer:代表网页的来源,即上一页的地址。如果输入网址访问,则没有该头信息。
Referer实现防盗链:在web服务器层面,根据http协议的Referer头信息判断,如果来自站外,则统一重定向到一个防盗链图片去。
响应头部字段
-
Accept-Ranges:bytes/none 服务器是否能处理范围请求
-
ETag:服务器上资源的唯一标识,当资源改变时该值也会改变
-
Location:重定向的URI值
-
Proxy-Authenticate:代理服务器所要求的认证信息
-
Retry-After:告诉客户端多久以后再来访问
-
WWW-Authenticate:告诉客户端认证方案
实体头部字段
请求和响应中实体所使用的头部字段
-
Allow:服务器所支持的请求方法
-
Content-Encoding:服务器对主体部分的编码格式
-
Content-Language:返回主体部分的语言
-
Content-Length:主体部分的大小(字节)
-
Content-Type:主体部分的媒体类型
-
Content-Range:范围请求时,服务端返回的资源范围
-
Last-Modified:资源最后修改时间
-
Expires:资源修改时间
HTTP缓存控制
-
响应头部
ETag:某个资源的指纹
Last-Modified:某个资源最后的修改时间 -
请求头部
If-Modified-Since:上次请求时,响应返回的Last-Modified字段的值
If-None-Match:上次请求时,响应返回的ETag的值
这两对请求头和响应头配合可以实现缓存,客户端请求数据时带上这两个头部字段,服务端判断如果该时间后没有修改数据或者ETag值没有发生改变,则服务端返回304,客户端使用缓存即可。
HTTP持久连接
初期的HTTP协议,每进行一次HTTP请求就要断开一次TCP连接,这样就造成了无畏的TCP连接和断开,增加了通信量的开销。
HTTP1.1时,实现了HTTP的持久连接,即建立一次TCP连接可以进行多次HTTP请求,只要任意一端没有提出断开连接,TCP会一直保持连接。这样做可以减少TCP建立和断开的开销,提高HTTP请求和响应速度。HTTP1.1中所有连接默认是持久连接的。
Cookie状态管理
由于HTTP是无状态的,服务器就无法根据之前的状态对本次请求进行处理。所以加入了Cookie机制,当客户端第一次请求时,服务端会返回一个Set-Cookie的头部字段通知客户端保存Cookie信息,客户端下次请求时会在报文中添加头部字段Cookie,发送给服务端,这样服务端就可以识别是哪个客户了。
HTTPS
使用HTTP进行通信时可能存在信息窃听或身份伪装等安全问题。
HTTP的不足
- 通信使用明文,内容可能被窃听
- 不验证通信方的身份,因此有可能遭遇伪装
- 无法证明报文的安全性,所有有可能已遭篡改
HTTPS定义
添加了加密以及认证机制的HTTP称为HTTPS。
HTTPS = HTTP + 加密 + 认证 + 完整性保护
加密
-
对称加密(共享秘钥加密)
加密和解密所使用同一个秘钥,这个秘钥不能泄漏。
问题:由于秘钥是惟一的,秘钥可能被泄漏。
-
非对称加密(公开秘钥加密)
公钥和私钥配对成一组秘钥,公钥是任何人都可以获取是公开的,私钥要保密。发送信息时,使用对方的公钥进行加密,对方收到密文后用自己的私钥解密即可。
问题:由于公钥是公开的,而且公钥可以解密私钥加密的内容,所以服务器向客户端发送数据时不安全的。
-
对称加密+非对称加密
开始使用非对称加密协商出一个秘钥,然后使用该秘钥用对称加密传输数据。
问题:可能遇到中间人问题,即协商秘钥阶段客户端向服务器请求公钥时,黑客会介入给客户端返回假的公钥,同时它会转发请求,以获取到服务端加密得到的后序使用的秘钥。
HTTPS加密认证过程
为了解决中间人返回假公钥的问题,这里引入CA认证,服务器不再给客户端直接返回公钥,而是将自己的公钥给CA认证机构,CA认证机构用自己的私钥将服务器的公钥加密为证书,这时客户端会向服务器请求证书,服务器返回证书后,客户端只需要使用CA机构的公钥就可以将证书解密得到服务器的公钥,而CA机构的公钥一般都是内置在浏览器客户端中的。经过上面过程客户端得到的公钥是真实无误的,接下来就通过非对称加密与服务器协商秘钥,再得到秘钥后客户端和服务器就进行对称加密通信了。
TCP/IP协议
把与互联网相关联的协议集合起来总称为TCP/IP协议。
分层
-
应用层
决定了向用户提供应用服务时通信的活动,HTTP、FTP和DNS处于该层。 -
传输层
提供处于网络连接中的两台计算机之间的数据传输,TCP、UDP处于该层。 -
网络层
处理数据包,数据包是网络传输的最小数据单元,该层规定通过怎样的路径到达对方计算机,并把数据包传给对方,IP处于该层。 -
数据链路层
处理连接网络的硬件部分。
TCP连接的三次握手
TCP三次握手建立连接.png名词解释
SYN:同步位 请求建立连接
seq:序列号 每个报文都有一个seq字段
ACK:确认位 1代表报文是有效的
ack :确认位的值
建立连接过程
-
第一次握手:客户端发送带有同步位SYN和序列号seq报文给服务器,请求建立连接。
-
第二次握手:服务器向客户端发送带有ACK确认位的确认报文,ack是确认位值,表示收到了客户端的请求报文。
-
第三次握手:客户端向服务器发送确认报文,表示客户端收到服务器发送的确认报文。
TCP断开的四次挥手
TCP四次挥手断开连接.png名词解释
FIN:终止位 期望断开连接
断开连接过程
-
第一次挥手:客户端发送带有终止位FIN的报文给服务器,请求断开连接。
-
第二次挥手:服务器发送带有确认位ACK的报文给客户端,表示确认收到断开请求,此时客户端一边的连接断开,客户端不再发送数据。
-
第三次挥手:服务器发送带有终止位FIN的报文给客户端,请求断开连接。
-
第四次挥手:客户端发送带有确认位ACK的报文给服务器,表示确认收到断开请求,可以断开,到此TCP连接就彻底断开了。
注:第二次和第三次挥手之间,服务器可能还会给客户端发送数据。
常见问题
-
为什么TCP建立连接需要三次握手,两次不行吗?
由于客户端发出的连接请求报文可能在网络中滞留,以至到连接释放某个时间点才到达服务器。这是一个失效的报文,但服务器以为是新的连接请求,就会向客户端发送确认报文,如果只有两次握手的话,那么此时连接就建立了。由于客户端此时没有发送建立连接请求,并不会理会服务器,也不会发送数据,而服务器却一直等待客户端发送数据,这样就造成了资源的浪费。
-
为什么TCP断开连接需要四次挥手?
因为双方关闭连接要经过双方都同意。首先是客户端发送一个FIN报文要求断开连接,服务器回应ACK确认;然后是服务器发送FIN报文要求断开连接,客户端回应ACK确认。
-
为什么TIME-WAIT状态需要经过2MSL时间才会变成CLOSED状态?
因为由于网络环境问题,客户端最后发送的ACK报文可能没有到达服务器,这时服务器就会认为是自己的FIN报文没有发送成功,所以会再次发送FIN报文到客户端请求断开。所以,这里等待2MSL时间内如果没有再次收到服务端的FIN报文的话,状态就可以置为CLOSED了。
网友评论