HTTP协议小结

简介

HTTP协议是基于TCP/IP协议来传递数据的应用层协议,规定了客户端和服务器之间的通信格式,其默认端口为80,HTTP是无连接无状态的。

主要特点:

  1. 简单快速:客户向服务器请求服务时只需要传送请求方法和路径,请求方法常用的有GET,POST,不同方法规定了客户和服务器不同的联系类型。协议通信速度很快。
  2. 灵活:HTTP协议允许传输任意类型的数据对象,正在传输的类型由Content-Type加以标记。
  3. 无连接:限制每次连接只处理一个请求,服务端确定用户端收到了处理后的结果之后,立刻断开连接。节省传输时间。
  4. 无状态:HTTP协议是无状态协议。无状态指的是协议对于事务处理没有记忆能力。
  5. 支持BS及CS模式

URL

http://host[:port][abs_path]

例如:

https://www.baidu.com/s?wd=HttP%E5%8D%8F%E8%AE%AE%E6%80%BB%E7%BB%93&rsv_spt=1&rsv_iqid=0xbb6ac0d200022f6c&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&rqlang=cn&tn=baiduhome_pg&rsv_enter=1&oq=HttP%25E6%2580%25BB%25E7%25BB%2593&inputT=7363&rsv_t=089bmiWk56%2BnKt5Ljs7CZihPEekxaufgYcpdefPyy4J6qS3KjJEt6Qzyg5XhLwQPRZTF&rsv_pq=c43d53970003ea1e&rsv_sug3=58&rsv_sug1=42&rsv_sug7=100&rsv_sug2=0&rsv_sug4=8625&rsv_sug=2

  • 协议部分:如http,https,tcp,其后加://
  • 域名部分:www.baidu.com,合法的Internet主机域名或者IP地址
  • 端口部分:指定一个端口,拥有被请求资源的服务器主机监听该端口的TCP连接。如果port为空,HTTP协议默认为80,HTTPS协议默认为443。
  • 虚拟目录部分:从域名的第一个/开始到最后一个/为止。
  • 文件名部分:从域名后的最后一个/开始到?为止,是文件名部分,如果没有?文件名部分:从域名后的最后一个“/”开始到“?”为止,是文件名部分,如果没有“?”,则是从域名后的最后一个“/”开始到“#”为止,是文件部分,如果没有“?”和“#”,那么从域名后的最后一个“/”开始到结束,都是文件名部分。
  • 锚部分:从“#”开始到最后,都是锚部分。
  • 参数部分:从“?”开始到“#”为止之间的部分为参数部分,又称搜索部分、查询部分。

URL和URI的区别:

URL URI
全名 Uniform resource locator Uniform resource identifier
用途 url可以用来标识一个资源,还指明了如何locate这个资源 定位web上可用的各种资源文件
组成 协议+IP地址(端口)+主机资源的具体地址 访问资源的命名机制+存放资源的主机名+资源自身的名称

请求消息Request

客户端发送一个HTTP请求到服务器的请求消息包含:

  • 请求行
  • 请求头部
  • 空行
  • 请求数据

    Alt text

  1. 请求行:说明请求类型,要访问的资源以及使用的HTTP版本
  2. 请求头部:说明服务器要使用的附加信息,host将指出请求的目的地,User-Agent。
  3. 空行:强制空行划分请求头和请求数据
  4. 请求数据:也叫请求主题,可以添加任意的其他数据。

请求头的常用字段:

  • Accept:告诉服务器,客户机支持的数据格式
  • Accept-Charset:告诉服务器,客户机采用的编码
  • Accept-Encoding:告诉服务器,客户机支持的数据压缩格式
  • Accept-language:用于告诉服务器,资源缓存的时间
  • Host:用于告诉服务器,客户机向访问的主机名
  • If-Modified-Since:用于告诉客户机,资源缓存的时间
  • Referer: 用于告诉服务器,客户机是从哪个资源链接到本资源的
  • User-Agent:客户机通过这个头可以向服务器带数据。
1
2
3
4
5
6
7
8
9
Accept: text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, */*; q=0.01
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7,ja;q=0.6
Connection: keep-alive
Cookie: BAIDUID=CDFD2D15954E6F99667163D726B3A3E4:FG=1; BIDUPSID=CDFD2D15954E6F99667163D726B3A3E4; PSTM=1500866515; BDUSS=hEYVF-Wmpka0lRLXMwWGRQZmtiVkViUDB5OVJnblNrQVpEM29EcHJPZ2JMS1paSUFBQUFBJCQAAAAAAAAAAAEAAAD0yYIxX8biX9fTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABufflkbn35ZWj; MCITY=-131%3A; BD_UPN=12314753; H_PS_PSSID=1445_21099_20928; BD_CK_SAM=1; PSINO=1; H_PS_645EC=b5cdqANCiMatErji8Z8BouSUOvY79iH5o%2Fjy%2FUKJM0yMzqrgjyQy2ee4g9p7aR60t86a
Host: www.baidu.com
Referer: https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=2&tn=baiduhome_pg&wd=http%E8%AF%B7%E6%B1%82%E5%A4%B4%E4%B8%AD%E7%9A%84%E5%AD%97%E6%AE%B5&rsv_spt=1&oq=http%25E8%25AF%25B7%25E6%25B1%2582&rsv_pq=c189685100052af0&rsv_t=596djY6Nc%2B2XuiZI2%2BAjz0DgMcM0Kn2EZBS1dtxl4a3ykgijQGu4DuQ3OjfSPXh6SjPu&rqlang=cn&rsv_enter=1&rsv_sug3=5&rsv_sug1=4&rsv_sug7=100&rsv_sug2=0&inputT=5807&rsv_sug4=6646
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36
X-Requested-With: XMLHttpRequest

消息相应Response

消息相应由四部分组成:

Alt text

  • 状态行:由HTTP协议版本号,状态码,状态消息三部分组成
  • 消息报头:说明客户端要使用的一些附加信息
  • 空行:分割用,必须
  • 响应正文:服务器返回给客户端的文本信息

状态码:

  1. 1XX:指示信息,表示请求已经接收,继续处理
  2. 2XX:成功,表示请求已经被成功接收
  3. 3XX:重定向,要完成请求需要进行更进一步的操作
  4. 4XX:客户端错误,请求有语法错误或者请求无法实现
  5. 5XX:服务器内部错误。

常见状态码:

  • 200 OK
  • 400 bad Request
  • 401 Unauthorized
  • 403 Forbidden
  • 404 Not Found
  • 500 Internal Server Error
  • 503 Server Unavailable

常见响应头

  • Location:这个响应头配合302状态码使用,用于告诉客户机资源的地址
  • Server:服务器通过这个头,告诉浏览器服务器的类型
  • Content-Encoding:服务器通过这个头,告诉浏览器数据压缩的格式
  • Content-Length:服务器通过这个头,告诉浏览器回送数据的长度
  • Content-Type:服务器通过这个头,告诉浏览器回送数据的类型
  • Last-Modified:服务器通过这个头,告诉浏览器当前资源缓存时间
  • Refresh:服务器通过这个头,告诉浏览器隔多长时间刷新一次
  • Content-Disposition:服务器通过这个头,告诉浏览器以下载方式打开数据
  • Transfer-Encoding:服务器通过这个头,告诉浏览器数据传送的格式
  • ETag:缓存相关的头,和Last-Modified功能一样,不过实时性更强(Last-Modified是一秒内即使内容更新也让浏览器找缓存)
  • Expires:服务器通过这个头,告诉浏览器把回送的资源缓存多长时间,0或-1表示不缓存
  • Cache-Control:no-cache
  • Pragma: no-cache

HTTP请求方法

HTTP1.0定义了三种请求方式,get、post、head,HTTP1.1新增了五种请求方法,options、put、delete、trace、connect。

  • GET:请求指定的页面信息,并返回实体主体
  • HEAD:类似于GET请求,只不过返回的响应中没有具体的内容,用于获取报头。
  • POST:向指定资源提交数据进行处理请求,数据被包含在请求体中,POST请求可能会导致新的资源的尽力或者已有资源的修改。
  • PUT:从客户端向服务器传送的数据取代指定的文档的内容。
  • DELETE:请求服务器删除指定的页面。
  • CONNECT:HTTP1.1协议中预留给能够将连接改为管道方式的代理服务器。
  • OPTIONS:允许客户端查看服务器性能。
  • TRACE:回显服务器收到的请求,主要用于测试或诊断。

HTTP工作原理

HTTP协议采用了请求/响应模型,客户端向服务器发送一个请求报文,请求报文包含请求的方法,URL,协议版本,请求头部和请求数据。服务器以一个状态行作为相应,相应的内容包括协议的版本,成功或者错误代码,服务器信息,响应头部和响应数据。

HTTP请求响应的步骤:

  1. 客户端连接到Web服务器,HTTP客户端,比如浏览器,与Web服务器的HTTP端口建立一个TCP套接字连接。

  2. 发送HTTP请求,通过TCP套接字,客户端向Web服务器发送一个文本的请求报文,一个请求报文由请求行,请求头部,空行和请求数据四部分组成。

  3. 服务器接收请求并返回HTTP响应,Web服务器解析请求,定位请求资源。服务器将资源副本写到TCP套接字,由客户端读取。一个响应由状态行、响应头部,空行和响应数据4部分组成。

  4. 释放TCP连接,如果Connection模式为close,则服务器主动关闭TCP连接,客户端被动关闭连接,释放TCP连接;若connection模式为keepalive,则该连接会保持一段时间,在该时间内可以继续接受请求。

  5. 客户端浏览器解析HTML内容。浏览器解析状态行,查看表明请求是否成功的状态代码,然后解析每一个响应头,响应头告知一下若干字节的HTML文档和文档的字符集。客户端浏览器读取响应数据HTML,根据HTML语法对其进行格式化,并在浏览器窗口中显示。

GET和POST请求的区别

GET POST
提交 GET提交,请求的数据会附在URL之后,也就是讲数据放在HTTP协议头之内,以?分隔URL和传输数据,多个参数用&连接 POST提交,把提交的数据放置在HTTP包的包体中,不像get提交会在地址栏上显示出来
传输数据大小 特定浏览器和服务器对URL长度有限制,get请求会收到URL长度的限制 理论上不受到任何限制
安全性 get提交数据,例如用户名和密码将明文出现在URL上 安全性较高
  • HTTP get,post,soap协议都是在HTTP上运行的

    • get:请求参数是作为一个key-value键值对的序列附加到URL上,查询字符串长度受到浏览器和服务器的限制,不适合传输大型数据集且其极不安全。

    • psot:请求参数是在HTTP标题的一个不同部分传输的,这一部分用来传输表单信息,因此必须将contentType设置为application/x-www-form- urlencoded。POST参数也是key-value键值对。但是它不支持复杂类型数据,因为POST没有定义传输数据结构的语义和规则。

    • soap:http POST的一个专用版本,遵循一种特殊的XML消息格式,contentType设置为text/xml 任何数据都可以xml化。

TCP连接建立过程

Alt text

  1. 两端TCP进程都是处于关闭状态,A是主动打开连接,B是被动打开连接。
  2. A的TCP客户端进程向B发出连接请报文段,这时首部中的同步位SYN=1,同时选择一个初始序号seq=x。TCP规定,SYN报文段不能携带数据但要消耗一个序号。这时,A的客户进程就进入SYN-SENT状态(同步已发送)。
  3. B收到连接请求报文之后,向A发送确认。在确认报文段中把SYN和ACK位都设置为1,确认号是ack=x+1,同时也为自己选择一个初始序号seq=y。这个报文段也不携带信息但是要消耗掉一个序号。这时B的TCP进程就进入SYN-RCVD(已收到同步)状态。
  4. A的TCP客户端收到B的确认后,还要向B给出确认,确认报文段的ACK设置为1,确认号ack=y+1,而自己的序号seq=x+1。这时TCP连接已经建立,A进入ESTABLISHED(已建立连接)状态。
  5. B收到A的确认后,也会进入ESTABLISHED状态。
  • 为什么A还要再发送一次确认呢?
    是为了防止已失效的连接请求报文段突然又回传到了B,而产生错误。(该报文段可能因为网络延时而失效)

TCP连接断开的过程

Alt text

  1. 断开连接时,发起方可以是客户端也可以是服务端。发起方会先发送一个FIN包,就进入FIN_WAIT状态,因此就不能发送用户数据,等待响应方回复ACK。

  2. 响应方收到FIN包后,就给发起方回复ACK。此时,响应方进入CLOSE_WAIT状态,因此响应方还有待发送的数据,需要等待发送完毕,才能关闭连接(发起方在发送FIN前,会保证已经发送完数据)。

  3. 发起方收到ACK后,就进入FIN_WAIT_2。此时还能继续接受数据,直到收到响应方的FIN。

  4. 响应方等数据发送完毕后,就给发起方发送FIN包。

  5. 发起方收到响应方的FIN包后,就进入TIME_WAIT状态,并向响应方发送ACK。

  6. 响应方收到ACK后,就进入CLOSE状态,完成了断开流程。

  7. 发起方的TIME_WAIT状态会持续2MSL(最大报文生存时间)。然后进入到CLOSED。

  • 为何是四次握手?
    响应方还有待发送端 数据,需要数据发送完才能发SYN包。

  • 为什么需要TIME_WAIT状态?
    因为在发起方发送ACK之后,不保证响应方一定能收到ACK。响应方在发送FIN后,就等待发起方的ACK,在等待一段时间之后,如果没有收到ACK,就会重发FIN包。发起方在TIME_WAIT的时间内如果又收到了FIN包,就会在发送ACK包。

Donate comment here