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
信息来指明数据长度