HTTP报文详细解析
以下是对 HTTP GET 请求报文 的详细解析,结合示例报文逐部分说明其结构和含义:
一、HTTP GET 请求的整体结构
GET 请求是 HTTP 协议中用于「获取资源」的方法,其报文由以下三部分组成(没有请求体,区别于 POST 请求):
- 请求行(Request Line)
- 请求头(Request Headers)
- 空白行(Empty Line)
二、示例报文解析(以用户提供的为例)
GET /servlet05/getServlet?username=lucy&userpwd=1111 HTTP/1.1 请求行
Host: localhost:8080 请求头
Connection: keep-alive
sec-ch-ua: "Google Chrome";v="95", "Chromium";v="95", ";Not A Brand";v="99"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: http://localhost:8080/servlet05/index.html
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
空白行
请求体(GET请求无请求体)
三、各部分详细说明
1. 请求行(Request Line)
格式:方法 + 资源路径 + HTTP协议版本
GET
:请求方法,表示「获取资源」。/servlet05/getServlet?username=lucy&userpwd=1111
:- 前半部分
/servlet05/getServlet
是 资源路径(URI),表示请求的目标资源。 - 后半部分
?username=lucy&userpwd=1111
是 查询参数(Query Parameters),格式为key=value&key=value
,用于向服务器传递数据(如用户输入的用户名和密码)。
- 前半部分
HTTP/1.1
:使用的 HTTP 协议版本(常见版本:1.0、1.1、2.0)。
2. 请求头(Request Headers)
请求头包含客户端环境、请求细节等信息,格式为 字段名: 值
,常见字段如下:
Host: localhost:8080
:- 表示请求的目标服务器地址和端口(
localhost
是本地主机,8080
是 Tomcat 默认端口)。
- 表示请求的目标服务器地址和端口(
Connection: keep-alive
:- 表示希望与服务器保持长连接(HTTP/1.1 默认为长连接),减少多次请求的开销。
sec-ch-ua: ...
(浏览器指纹字段):- 用于传递浏览器信息(品牌、版本、操作系统等),示例中表明用户使用 Chrome 95 浏览器,操作系统为 Windows。
User-Agent: ...
:- 完整的客户端标识字符串,包含浏览器、操作系统、引擎等信息(服务器可据此判断客户端类型,如区分 PC 或移动端)。
Accept: ...
:- 客户端支持的响应内容类型(如
text/html
表示接受 HTML 页面,application/json
表示接受 JSON 数据),q=0.9
表示优先级(数值越高越优先)。
- 客户端支持的响应内容类型(如
Referer: http://localhost:8080/servlet05/index.html
:- 表示当前请求是从哪个页面发起的(即「来源页面」),服务器可借此统计来源或防止跨站请求伪造(CSRF)。
Accept-Encoding: gzip, deflate, br
:- 客户端支持的响应压缩算法(如
gzip
压缩可减少传输数据量)。
- 客户端支持的响应压缩算法(如
Accept-Language: zh-CN,zh;q=0.9
:- 客户端偏好的语言(服务器可据此返回对应语言的内容,如中文页面)。
3. 空白行(Empty Line)
- 位于请求头和请求体之间,用于分隔两部分(GET 请求无请求体,此处空白行后直接结束)。
4. 请求体(Request Body,GET 请求中不存在)
- GET 请求没有请求体,数据通过 URL 中的查询参数传递。
- POST 请求 才有请求体,用于传递大量数据(如表单提交的二进制文件、JSON 数据等)。
四、GET 请求的特点总结
- 无请求体:数据通过 URL 的查询参数传递,长度受浏览器限制(通常不超过 2048 字符)。
- 幂等性:多次相同的 GET 请求不会对服务器资源产生副作用(仅读取数据,不修改)。
- 可见性:查询参数直接显示在 URL 中,可能被浏览器缓存或记录在日志中,不适合传递敏感数据(如密码,示例中虽传递了
userpwd
,但实际开发中应避免)。 - 用途:常用于获取资源(如查询数据、访问页面)。
五、服务器如何处理 GET 请求的参数
在 Java Servlet 中,通过 HttpServletRequest
对象获取 GET 请求参数:
String username = request.getParameter("username"); // 得到 "lucy"
String userpwd = request.getParameter("userpwd"); // 得到 "1111"
通过以上解析,可以清晰理解 HTTP GET 请求的报文结构及各部分的作用,这对调试 Web 应用、分析网络请求非常重要。
六、服务器如何处理 GET 请求的参数
当服务器接收到客户端的 HTTP GET 请求后,会根据请求内容进行处理,并返回一个 HTTP 响应报文。HTTP 响应报文由状态行、响应头、空白行和响应体四部分组成。下面是一个可能针对上述 GET 请求的响应报文示例,并对其进行详细解析。
示例响应报文
HTTP/1.1 200 OK 状态行
Date: Tue, 08 Apr 2025 12:00:00 GMT 响应头
Server: Apache/2.4.41 (Ubuntu)
Content-Type: text/html; charset=UTF-8
Content-Length: 1234
Connection: keep-alive
<!DOCTYPE html>
<html>
<head>
<title>Response Page</title>
</head>
<body>
<h1>Hello, Lucy!</h1>
<p>Your request has been processed successfully.</p>
</body>
</html>
空白行
响应体
各部分详细解析
1. 状态行(Status Line)
格式为:HTTP 协议版本 + 状态码 + 状态消息
HTTP/1.1
:表示使用的 HTTP 协议版本,与请求报文保持一致,这里使用的是 HTTP 1.1 版本。200
:状态码,是一个三位数字,用于表示请求的结果。200
表示请求成功,服务器已经成功处理了客户端的请求。常见的状态码还有404
(未找到资源)、500
(服务器内部错误)等。OK
:状态消息,是对状态码的文本描述,方便开发者和用户理解状态码的含义。
2. 响应头(Response Headers)
响应头包含了服务器的相关信息、响应内容的元数据等,格式为 字段名: 值
。
Date: Tue, 08 Apr 2025 12:00:00 GMT
:表示响应生成的日期和时间,采用格林威治标准时间(GMT)格式。Server: Apache/2.4.41 (Ubuntu)
:表明服务器的类型和版本,这里使用的是 Apache 服务器,版本为 2.4.41,运行在 Ubuntu 操作系统上。Content-Type: text/html; charset=UTF-8
:指定响应内容的类型和字符编码。text/html
表示响应内容是 HTML 格式,charset=UTF-8
表示使用 UTF - 8 字符编码,确保文本能正确显示各种语言字符。Content-Length: 1234
:表示响应体的长度,单位是字节。客户端可以根据这个长度来确定接收数据的结束位置。Connection: keep-alive
:与请求头中的Connection
字段对应,表示服务器希望与客户端保持长连接,以便后续的请求可以复用该连接。
3. 空白行(Empty Line)
用于分隔响应头和响应体,表明响应头部分结束,接下来是响应体的内容。
4. 响应体(Response Body)
响应体包含了服务器返回给客户端的实际数据,根据 Content-Type
字段的不同,响应体可以是 HTML 页面、JSON 数据、图片等。在这个示例中,响应体是一个 HTML 页面,包含一个标题和一段文本信息。
服务器生成响应的示例代码(Java Servlet)
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/servlet05/getServlet")
public class MyGetResponseServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置响应的状态码
response.setStatus(HttpServletResponse.SC_OK);
// 设置响应头
response.setContentType("text/html; charset=UTF-8");
// 获取响应输出流
PrintWriter out = response.getWriter();
// 生成响应体
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("<title>Response Page</title>");
out.println("</head>");
out.println("<body>");
String username = request.getParameter("username");
out.println("<h1>Hello, " + username + "!</h1>");
out.println("<p>Your request has been processed successfully.</p>");
out.println("</body>");
out.println("</html>");
}
}
代码解释
response.setStatus(HttpServletResponse.SC_OK)
:设置响应的状态码为 200,表示请求成功。response.setContentType("text/html; charset=UTF-8")
:设置响应内容的类型为 HTML 格式,并使用 UTF - 8 字符编码。PrintWriter out = response.getWriter()
:获取响应输出流,用于向客户端发送响应体内容。- 通过
out.println()
方法生成 HTML 格式的响应体内容,并根据请求参数中的username
动态显示欢迎信息。
通过以上内容,你可以了解 HTTP 响应报文的结构和各部分的作用,以及如何在 Java Servlet 中生成响应。
Javaweb 文章被收录于专栏
JavaWeb 是指使用 Java 技术来开发基于 Web 的应用程序,它结合了 Java 语言的强大功能和 Web 技术的灵活性,广泛应用于各种企业级 Web 应用开发中。