0、前言
准备做一个Linux网络服务器应用实战,通过网页和运行在Linux下的服务器程序通信,这是第一篇,先简单介绍一下HTTP协议。
1、概述
1.1 定义
HTTP(Hypertext Transfer Protocol)是一种用于传输超文本数据的应用层协议,是互联网上应用最为广泛的协议之一。HTTP协议的主要作用是在客户端和服务器之间传输和交换文本、图片、视频等超文本数据。
1.2 场景
- 网页浏览:HTTP用于浏览器与Web服务器之间的通信,请求网页内容并将其呈现给用户。
- 文件下载:通过HTTP下载文件,如图片、视频、文档等。
- API通信:许多Web服务和应用程序使用HTTP作为API的通信协议,通过HTTP请求和响应进行数据交换。
- 表单提交:用户在网页上填写表单并提交数据时,通常使用HTTP POST请求将表单数据发送给服务器
2、HTTP协议格式
HTTP 协议包含请求和响应两种类型。请求是客户端向服务器发送的信息,用于请求某种操作或资源,而响应是服务器对客户端请求的回复,包含请求的结果或所请求的资源。
2.1 请求
HTTP 请求的结构如下:
- 请求行(Request Line):包含请求方法、请求目标和协议版本。
- 请求头部(Request Headers):包含客户端向服务器发送的请求信息,每个头部字段为
HeaderName: HeaderValue
。 - 空行(Empty Line):用于分隔请求头部和请求体。
- 请求体(Request Body):可选,包含客户端向服务器发送的数据。
一个简单示例:
POST /login HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0
Content-Type: application/json
Content-Length: 45
Accept-Language: en-US
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoxMjM0NTY3ODkwLCJleHBpcmVkX3N0YW5kYXJkX2RhdGEiOiIyMDIyLTAxLTAxIn0.2jV1rYVzLQrWg4O1hW5x6P0fJfGKs1P6Wzg6D7eJz-0{"username": "john_doe", "password": "secretpassword"}
解释每一行的作用:
-
请求行(Request Line):
POST /login HTTP/1.1
:请求方法为 POST,请求的资源路径为 /login,HTTP 协议版本为 HTTP/1.1。请求行是必须的,用于指定请求的方法、路径和协议版本。
-
请求头部字段(Request Headers):
Host: www.example.com
:指定请求的目标主机。User-Agent: Mozilla/5.0
:标识客户端的用户代理。Content-Type: application/json
:指定请求体的内容类型为 JSON 格式。Content-Length: 45
:指定请求体的长度。Accept-Language: en-US
:指定客户端接受的语言。Authorization: Bearer ...
:包含身份验证信息,例如 JWT token。
-
空行(Empty Line):
- 空行用于分隔头部字段和请求体。
-
请求体(Request Body):
{"username": "john_doe", "password": "secretpassword"}
:请求体包含 JSON 格式的数据,通常用于传递用户输入或其他信息。
2.1.1 请求行
HTTP 请求行由三个部分组成,分别是请求方法(Method)、请求目标(Request Target)和协议版本(HTTP Version)。
2.1.1.1 请求方法(Method)
指定客户端希望服务器对资源执行的操作类型,常见取值:
GET
:获取资源POST
:提交数据PUT
:更新资源DELETE
:删除资源HEAD
:获取资源的头部信息OPTIONS
:获取服务器支持的方法
2.1.1.2 请求目标(Request Target)
指定请求的目标资源的位置或标识符。请求目标可以是绝对路径(如 /login
)、绝对 URL(如 http://www.example.com/login
)或星号(*
,表示请求对整个服务器有效)。
其中http://www.example.com/login
是一个 URL(统一资源定位符),用于标识互联网上的资源位置。URL 由多个部分组成,每个部分的意义如下:
http://
:协议部分,指定访问资源时要使用的协议,这里是 HTTP 协议。www.example.com
:主机部分,指定主机名,即资源所在的服务器的域名或 IP 地址。/login
:路径部分,指定服务器上资源的具体路径或标识符,用于定位要访问的资源。
2.1.1.3 协议版本
指定客户端使用的 HTTP 协议版本,常见的取值包括:
HTTP/1.0
HTTP/1.1
HTTP/2.0
HTTP/3.0
2.1.2 请求头部字段
请求头部字段(Request Headers)包含了客户端向服务器发送的请求信息。请求头部中的每个头部字段都以一个单独的行开始,格式为HeaderName: HeaderValue
。当所有请求头部字段都添加完毕后,空行用于表示请求头部的结束,并告诉服务器请求头部已经完整,接下来是请求体(如果有的话)。其中一些常见的请求头部字段包括:
Host
:指定请求的目标主机名和端口号。User-Agent
:标识客户端的用户代理(浏览器或其他应用程序)。Accept
:指定客户端能够接受的内容类型。Accept-Language
:指定客户端能够接受的语言类型。Accept-Encoding
:指定客户端能够接受的内容编码方式。Connection
:指定客户端与服务器之间连接的管理方式。Cache-Control
:指定请求或响应的缓存行为。Content-Type
:指定请求体的内容类型(通常用于 POST 请求)。Content-Length
:指定请求体的长度(通常用于 POST 请求)。
在这些请求头部字段中,Host
是必选的,因为它指定了请求的目标主机。其他字段如 User-Agent
、Accept
、Accept-Language
等虽然不是必选的,但在实际应用中通常会包含这些信息,以便服务器能更好地理解客户端的需求和特性。
2.1.3 空行
空行是一个仅包含回车符(CR)和换行符(LF)的行,即\r\n
。
2.1.4 请求体
请求体(Request Body)是可选的,通常用于包含客户端向服务器发送的数据,比如表单数据、文件上传等。对于 GET 请求,通常不包含请求体,而对于 POST 请求,通常会包含请求体。请求体的格式和内容根据具体的应用场景和请求目的而定。
2.2 响应
HTTP响应的结构如下:
- 状态行(Status Line):包含协议版本、状态码和状态消息。
- 响应头部(Response Headers):包含服务器向客户端发送的响应信息,每个头部字段为HeaderName: HeaderValue
- 空行(Empty Line):用于分隔响应头部和响应体。
- 响应体(Response Body):包含实际的响应内容,如HTML文档、图片、视频等数据
一个简单示例:
HTTP/1.1 200 OK
Date: Mon, 01 Feb 2022 08:00:00 GMT
Server: Apache/2.4.6 (CentOS)
Content-Type: application/json
Content-Length: 36{"status": "success", "message": "Logged in successfully"}
解释每一行的作用:
-
状态行(Status Line):
HTTP/1.1 200 OK
:指定协议版本为 HTTP/1.1,状态码为 200,状态消息为 OK。状态行是必须的,用于表示服务器对请求的响应状态。
-
响应头部字段(Response Headers):
Date: Mon, 01 Feb 2022 08:00:00 GMT
:指定响应生成的日期和时间。Server: Apache/2.4.6 (CentOS)
:指定响应的服务器软件及版本信息。Content-Type: application/json
:指定响应体的内容类型为 JSON 格式。Content-Length: 36
:指定响应体的长度。
-
空行(Empty Line):
- 空行用于分隔响应头部字段和响应体。
-
响应体(Response Body):
{"status": "success", "message": "Logged in successfully"}
:响应体包含 JSON 格式的数据,通常用于返回处理结果或其他信息。
在上面的示例中,状态行是必须的,用于表示服务器对请求的响应状态。其他响应头部字段和响应体都是可选的,具体取决于服务器端返回的信息和响应的需求。例如,一些响应可能不需要响应体,而某些头部字段可能是必须的(如 Date
头部字段)。
2.2.1 状态行
状态行包含了以下内容:
-
协议版本(HTTP-Version):指定了使用的HTTP协议版本,通常是HTTP/1.0或HTTP/1.1。
- 必须的:是必须的,用于指明正在使用的HTTP协议版本。
-
状态码(Status-Code):指示了服务器对请求的处理结果,是一个三位数的数字代码。
- 必须的:是必须的,用于明确指示请求的处理结果。
- 常见的状态码包括:
-
1xx(信息性状态码):
- 100:继续
- 101:切换协议
-
2xx(成功状态码):
- 200:请求成功
- 201:已创建
- 204:无内容
-
3xx(重定向状态码):
- 301:永久重定向
- 302:临时重定向
- 304:未修改
-
4xx(客户端错误状态码):
- 400:错误的请求
- 401:未授权
- 403:禁止访问
- 404:未找到资源
-
5xx(服务器错误状态码):
- 500:服务器内部错误
- 501:未实现
- 503:服务不可用
-
-
状态消息(Reason-Phrase):是对状态码的简短描述,用于帮助理解状态码的含义。
- 可选的:不是必须的,但通常会包含一个简短的描述信息。
状态行的格式为 <HTTP-Version> <Status-Code> <Reason-Phrase>
,例如 HTTP/1.1 200 OK
。其中,协议版本和状态码是必须的,而状态消息是可选的,但通常会提供以便客户端能够更好地理解服务器对请求的处理结果。通过状态行,客户端可以快速了解服务器对请求的处理情况,从而采取相应的行动。
2.2.2 响应头部字段
响应头部(Response Headers)是HTTP响应中的一部分,包含了关于响应的元数据信息,用于传输关于响应的附加信息。响应头部通常由多个键值对组成,每个键值对表示一个头部字段和对应的值。以下是响应头部的一些常见字段和其作用:
-
Content-Type:指定了响应体的MIME类型,告诉客户端如何解析响应内容。例如,
Content-Type: text/html
表示响应体是HTML文档。 -
Content-Length:指定了响应体的长度(以字节为单位),用于告诉客户端响应体的大小。例如,
Content-Length: 1234
表示响应体长度为1234字节。 -
Date:指定了响应生成的日期和时间,帮助客户端了解响应的时间信息。例如,
Date: Tue, 12 Oct 2021 08:30:00 GMT
。 -
Server:指定了响应的服务器软件名称和版本号。例如,
Server: Apache/2.4.41 (Unix)
。 -
Cache-Control:指定了缓存控制策略,告诉客户端如何处理响应的缓存。例如,
Cache-Control: max-age=3600
表示客户端可以将响应缓存1小时。 -
Set-Cookie:用于在响应中设置Cookie,允许服务器向客户端设置会话标识等信息。例如,
Set-Cookie: sessionId=12345; Path=/; Expires=Wed, 12 Oct 2022 08:30:00 GMT
。 -
Location:指定了重定向的目标URL,用于告诉客户端进行重定向。例如,
Location: https://www.example.com/newpage
。
响应头部中的这些字段提供了关于响应的重要信息,帮助客户端正确解析和处理响应内容,以及控制缓存、重定向等行为。正确设置响应头部可以提高网站性能、安全性和用户体验。
2.2.3 空行
空行是一个仅包含回车符(CR)和换行符(LF)的行,即\r\n
。
2.2.4 响应体
响应体(Response Body)是HTTP响应的一部分,包含了实际的响应内容,例如HTML页面、JSON数据、图像等。响应体是服务器返回给客户端的主要内容,用于传输实际的数据信息。以下是响应体的一些重要特点和内容:
-
内容类型(Content-Type):响应头部中的
Content-Type
字段指定了响应体的MIME类型,告诉客户端如何解析响应内容。常见的MIME类型包括text/html
(HTML文档)、application/json
(JSON数据)、image/jpeg
(JPEG图像)等。 -
文本内容:响应体可以包含各种文本内容,如HTML、XML、JSON等。这些文本内容会被客户端解析和显示,以呈现给用户相应的信息。
-
二进制内容:响应体也可以包含二进制数据,例如图像、视频、音频等。这些二进制数据通常以字节流的形式传输,客户端可以根据内容类型进行解析和展示。
-
压缩:有时服务器会对响应体进行压缩,以减小传输数据量和提高性能。常见的压缩算法包括Gzip和Deflate,客户端在接收到压缩的响应体后需要解压缩才能处理数据。
-
错误信息:在发生错误时,响应体可能包含错误信息,用于告知客户端发生了何种错误以及可能的解决方案。例如,404 Not Found错误会返回一个包含错误信息的HTML页面。
响应体的内容直接影响了客户端的用户体验和功能实现。开发人员需要确保响应体的内容正确、完整,并根据需要设置合适的内容类型和编码方式,以确保客户端能够正确解析和处理响应内容。
3、总结
本文讲述了http协议的一般格式,对常用字段进行了详细阐述。