HTTP报文详细解析

以下是对 HTTP GET 请求报文 的详细解析,结合示例报文逐部分说明其结构和含义:

一、HTTP GET 请求的整体结构

GET 请求是 HTTP 协议中用于「获取资源」的方法,其报文由以下三部分组成(没有请求体,区别于 POST 请求):

  1. 请求行(Request Line)
  2. 请求头(Request Headers)
  3. 空白行(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 请求的特点总结

  1. 无请求体:数据通过 URL 的查询参数传递,长度受浏览器限制(通常不超过 2048 字符)。
  2. 幂等性:多次相同的 GET 请求不会对服务器资源产生副作用(仅读取数据,不修改)。
  3. 可见性:查询参数直接显示在 URL 中,可能被浏览器缓存或记录在日志中,不适合传递敏感数据(如密码,示例中虽传递了 userpwd,但实际开发中应避免)。
  4. 用途:常用于获取资源(如查询数据、访问页面)。

五、服务器如何处理 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 应用开发中。

全部评论

相关推荐

04-07 14:34
已编辑
同济大学 C++
1.自我介绍2.闲聊,包括毕业要求、什么时间可以来实习,可以实习多久等等3.介绍项目4.容器是如何实现隔离的?5.简历上异构多处理器计算资源调度算法有神么应用场景?6.容器向外界发送一个请求,比如www.baidu.com,怎么确保容器能够接收到这个请求呢?(我是结合容器内部的一个ip分配、容器运行时和内核之间的响应回答的)7.容器内部向www.baidu.com发送请求响应流程(实际上就是url的解析过程)8.docker容器的发展了解么?答:讲了一下docker之前的一些容器,比如lxc等等9.了解k8s么(这个很熟悉)10.对云原生了解么(云计算到边缘计算全讲了一遍)11.场景题,给你一个任务DAG,有计算密集型节点(对cpu使用比较多)、I/O通信密集型的,你怎么去实现高效调度呢?答:结合I/O多路复用回答的12.I/O多路复用发挥怎么个作用呢(这个之前面试刚问过,很熟悉)13.进程和线程?14.了解协程么15.http安全么?为什么?16.https的加密方式?17.https加密为什么要服务器发送一次密钥,客户端再向服务器发送?(这个尝试了两个答案,面试官没有很肯定)、18.http连接是哪一层的?19.http连接是tcp还是udp?算法题:hot100&nbsp;岛屿数量反问1.对今天面试有什么建议2.什么时候出结果——————————总体来说问的问题基本都回答上来了,没有出现卡壳的情况,就是最后算法题输入犯了个低级错误到最后才检查出来面试官看了我的思路觉得没问题,后续安慰了我一下。啊,不会因为这个输入的卡壳导致整段垮掉吧,我听说字节还是挺重视算法题的,悲、面试感受的话感觉问得其实挺深入的,但是因为都有详细了解所以都回答得出来,算法得多熟悉下ACM模式了,哭。——————————4.7&nbsp;进二面了,芜湖!
查看22道真题和解析
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务