目录

HTTP协议是如何工作的?原理是什么?

HTTP简介

HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写。

HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。

设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。通过HTTP或者HTTPS协议请求的资源由统一资源标识符(Uniform Resource Identifiers,URI)来标识。

2014年12月,互联网工程任务组(IETF)的Hypertext Transfer Protocol Bis(httpbis)工作小组将HTTP/2标准提议递交至IESG进行讨论,于2015年2月17日被批准。HTTP/2标准于2015年5月以RFC 7540正式发表,取代HTTP 1.1成为HTTP的实现标准。

当前常见的而且是使用最多的还是HTTP/1.1,遂本文以讲解HTTP/1.1为主。

网络通信分层

HTTP只是一种交换一些直观信息的协议,但网线里传输的是电平数据(即1和0)。HTTP与硬件之间还有数个流程,其分别遵守相应协议。

从接近应用程序(即浏览器等)到接近硬件的顺序分别有:

  • HTTP协议——传输应用相关信息
  • TCP协议——将上层数据封装为字节流,并完成链接建立的确认
  • IP协议——物理层寻址
  • 串行——物理层实质传输信号

然后就到网线了

HTTP协议

HTTP是基于客户端/服务端(C/S)的架构模型,也就是说,有一台电脑是服务器(如网站一端),一个是客户端(即浏览器)。

HTTP协议负责把数据(如网页文字信息,图片二进制数据)封装。它会加入其他的网络用的控制信息等等。

HTTP的一次数据包含:

  • 数据行
  • 头部
  • 数据实体

HTTP头

GET /hello.txt HTTP/1.1
User-Agent: curl/7.16.3 libcurl/7.16.3 OpenSSL/0.9.7l zlib/1.2.3
Host: www.example.com
Accept-Language: en, mi

如上是一段真实的HTTP请求(客户端->服务器)数据头。

HTTP/1.1 200 OK
Date: Mon, 27 Jul 2009 12:28:53 GMT
Server: Apache
Last-Modified: Wed, 22 Jul 2009 19:15:56 GMT
ETag: "34aa387-d-1568eb00"
Accept-Ranges: bytes
Content-Length: 51
Vary: Accept-Encoding
Content-Type: text/plain

如上是一段真实的HTTP响应(服务器->客户端)数据头。

数据行

两个头部的第一行就是数据行。由空格分为三段式,请求数据分别对应请求方法、请求URI、协议相应数据分别对应着协议、状态码、状态信息

协议

不重要的,现行广泛的是HTTP/1.1,新出的版本是HTTP/2.0,但资料较少、使用不多,以后再介绍吧。

请求方法

根据HTTP标准,HTTP请求可以使用多种请求方法。

HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法。

HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。

请求方法是客户端描述需要服务器的操作的文字。

方法 描述
GET 请求指定的页面信息,并返回实体主体。
HEAD 类似于GET请求,只不过返回的响应中没有具体的内容,用于获取数据头。
POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。
PUT 从客户端向服务器传送的数据取代指定的文档的内容。
DELETE 请求服务器删除指定的页面。
CONNECT HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
OPTIONS 允许客户端查看服务器的性能。
TRACE 回显服务器收到的请求,主要用于测试或诊断。
请求URI

统一资源标识符(英语:Uniform Resource Identifier,缩写:URI)。是一个文件目录的描述方式,用相对路径来描述。

scheme:[//[user[:password]@]host[:port]]/[path][?query][#fragment]

协议名:[//[用户名[:密码]@]服务器IP或域名[:端口]]/[相对路径][?请求数据][#片段名称]

其中用[]框起来的部分是可选内容,不一定必须存在。举几个例子。

https://zh.wikipedia.org/wiki/%E7%BB%9F%E4%B8%80%E8%B5%84%E6%BA%90%E6%A0%87%E5%BF%97%E7%AC%A6
协议名  服务器IP或域名    相对路径

https://uniapp.dcloud.io/?hmsr=jujin&hmpl=&hmcu=&hmkw=&hmci=
协议名  服务器IP或域名     请求数据1   请求数据2    请求数据3……

服务器IP或域名用于指定IP协议找到服务器,由TCP链接服务器对应端口上的应用。 服务器程序按照对应的协议、路径、数据和片段响应内容即可。

状态码和状态信息

这俩说的是一个事,我也不知道为啥要两个。

常见的HTTP状态码:(在数据行中,状态信息以英文出现。)

状态码 - 状态信息
200    - 请求成功
301    - 资源(网页等)被永久转移到其它URL
404    - 请求的资源(网页等)不存在
500    - 内部服务器错误

头部数据

在数据行下面是key-value对应的头部数据,每一行用\r\n间隔。(键名不区分大小写)

键和值之间是: (半角冒号和空格)间隔。

具体每一个数据信息可以到这查阅。

HTTP数据

一个完整的请求或者响应数据可能还包含数据体,比如上传、下载的文件等等。

这是一个完整的带有数据的请求。

POST /hello HTTP/1.1
User-Agent: curl/7.16.3 libcurl/7.16.3 OpenSSL/0.9.7l zlib/1.2.3
Host: www.example.com
Accept-Language: en, mi
Content-Length: 14

name=sedfewfwe

其中一个空行下面就是请求数据,与前面的头部以\r\n\r\n间隔。

这是一个完整的带有数据的响应。

空行也是同样的间隔。

值得注意的是,所有传输数据时需要在头部添加Content-Length信息来指明数据长度