JavaEE初阶——HTTP/HTTPS 核心原理:从协议格式到加密传输



---JavaEE专栏--- ⬅(click)


引言

在网络通信中,HTTP/HTTPS 是我们每天都在接触的应用层协议------打开浏览器访问网页、使用 App 加载数据,背后都离不开它们的支撑。本文将从 HTTP 基础概念出发,深入剖析协议格式、请求响应机制,再到 HTTPS 的加密原理与安全保障,结合实例代码与图表,帮你彻底掌握这两大协议的核心知识。

一、HTTP 基础:什么是超文本传输协议?

1.1 定义与定位

HTTP(HyperText Transfer Protocol,超文本传输协议)是应用层协议 ,诞生于 1991 年,目前主流版本为 HTTP/1.1 和 HTTP/2.0(HTTP/3 正在逐步普及,由 Google、Facebook 等率先支持)。

它的核心作用是:在客户端(如浏览器)和服务器之间传输"超文本"------不仅包括 HTML、CSS 等文本,还包括图片、视频、音频等二进制资源。

1.2 HTTP 在网络分层中的位置

HTTP 依赖传输层协议实现数据传输,不同版本对应不同的传输层协议:

HTTP 版本 依赖的传输层协议 特点
HTTP/0.9 ~ HTTP/2.0 TCP 面向连接、可靠传输
HTTP/3 UDP 基于 QUIC 协议,低延迟、高并发

从 OSI 参考模型与 TCP/IP 分层模型的对应关系来看,HTTP 位于应用层,下方依赖传输层、网络层等支撑:

1.3 HTTP 的工作流程

访问一个网站的过程,本质是多次 HTTP 请求/响应的交互,以搜狗搜索为例:

  1. 客户端(浏览器)输入 URL(如 https://www.sogou.com),向搜狗服务器发送 HTTP 请求;
  2. 服务器接收请求,处理后返回 HTTP 响应(包含 HTML 页面、CSS、JavaScript 等资源信息);
  3. 浏览器解析响应内容,渲染成用户看到的页面(过程中可能触发多次请求,如加载图片、字体)。

通过 Chrome 开发者工具(F12 → Network 标签)可观察详细请求过程,每一条记录都是一次完整的"请求-响应":

(实际使用时可自行打开搜狗主页查看)

二、HTTP 协议格式:请求与响应的结构

HTTP 是文本格式协议,请求和响应均由"首行 + 报头 + 空行 + 正文"四部分组成。通过 Fiddler 或 Chrome 抓包可直观看到格式细节。

2.1 HTTP 请求格式

请求报文的结构如下,以"西安交大就业网登录"的 POST 请求为例:

http 复制代码
POST http://job.xjtu.edu.cn/companyLogin.do HTTP/1.1  # 首行:方法 + URL + 版本
Host: job.xjtu.edu.cn                                 # 报头:键值对,冒号分隔
Connection: keep-alive
Content-Length: 36
Cache-Control: max-age=0
Origin: http://job.xjtu.edu.cn
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Referer: http://job.xjtu.edu.cn/companyLogin.do
Accept-Encoding: gzip,deflate
Accept-Language: zh-CN,zh;q=0.8
Cookie: JSESSIONID=D628A75845A74D29D991DB47A461E4FC; Hm_lvt_783e83ce0ee350e23a9d389df580f658=1504963710,1506661798; Hm_lpvt_783e83ce0ee350e23a9d389df580f658=1506661802

username=hgtz2222&password=222222222  # 正文:空行后的数据,长度由 Content-Length 指定
关键组成部分解析
部分 说明
首行 包含 3 个字段: - 方法(如 GET/POST) - URL(请求的资源路径) - HTTP 版本(如 HTTP/1.1)
报头(Header) 键值对结构,描述请求属性,如 Host(服务器地址)、Content-Type(正文格式)、Cookie(身份信息)
空行 报头与正文的分隔符,不可或缺(避免 TCP 粘包问题)
正文(Body) 可选,存放请求数据(如表单参数、JSON),长度由 Content-Length 标识

2.2 HTTP 响应格式

响应报文结构与请求类似,以"西安交大就业网登录成功"的响应为例:

http 复制代码
HTTP/1.1 200 OK  # 首行:版本 + 状态码 + 状态描述
Server: YxlinkWAF
Content-Type: text/html;charset=UTF-8
Content-Language: zh-CN
Transfer-Encoding: chunked
Date: Fri,29 Sep 2017 05:10:13 GMT

<!DOCTYPE html>  # 正文:HTML 页面内容
<html>
<head>
<title>西安交通大学就业网</title>
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<!-- 省略其他 HTML 内容 -->
</head>
<body>
<!-- 页面内容 -->
</body>
</html>
关键组成部分解析
部分 说明
首行 包含 3 个字段: - HTTP 版本 - 状态码(如 200 表示成功) - 状态描述(如 OK)
报头(Header) 描述响应属性,如 Content-Type(正文格式)、Date(响应时间)
空行 报头与正文的分隔符
正文(Body) 服务器返回的数据(如 HTML、JSON、图片二进制流)

2.3 协议格式总结

三、HTTP 核心概念详解

3.1 URL:统一资源定位符

URL(Uniform Resource Locator)即"网址",用于定位互联网上的资源,格式遵循 RFC1738 标准。

完整 URL 格式
复制代码
http://user:pass@www.example.jp:80/dir/index.htm?uid=1#ch1
├─协议─┘ ├─登录信息─┘ ├─服务器地址─┘ ├─端口─┘ ├─文件路径─┘ ├─查询字符串─┘ ├─片段标识─┘
各部分说明(含可省略规则)
部分 说明 可省略规则
协议(Scheme) 如 http、https、jdbc:mysql,指定访问协议 可省略,默认 http://
登录信息 用户名:密码,用于身份认证 现代网站已弃用,默认省略
服务器地址 域名(如 www.sogou.com)或 IP(如 118.24.113.28),域名需 DNS 解析 不可省略(除非是相对路径)
端口号 如 80(HTTP 默认)、443(HTTPS 默认) 可省略,按协议自动填充默认端口
文件路径 资源在服务器上的路径,如 /dir/index.htm 可省略,默认 /(服务器可能映射到 index.html)
查询字符串 键值对结构(如 uid=1&name=zhangsan),用于传递参数 可省略
片段标识 用于页面内跳转(如 Vue 文档的章节锚点) 可省略
URL Encode:特殊字符转义

URL 中 ?/+ 等字符为特殊用途,若参数中包含这些字符或中文字符,需转义为 %XY 格式(XY 为字符的 16 进制 ASCII 码)。

示例:

  • C++ 转义为 C%2B%2B
  • 陕西 转义为 %E9%99%95%E8%A5%BF

3.2 HTTP 方法(Method)

方法定义了请求的"语义",即客户端对服务器资源的操作类型。主流方法及说明如下:

方法 说明 支持版本 幂等性(多次请求结果一致)
GET 获取服务器资源(如访问网页、查询数据) 1.0/1.1
POST 提交数据到服务器(如登录、上传表单) 1.0/1.1
PUT 更新服务器资源(全量更新,如修改用户信息) 1.0/1.1
DELETE 删除服务器资源 1.0/1.1
HEAD 仅获取响应头(不返回正文,用于检查资源是否存在) 1.0/1.1
OPTIONS 查询服务器支持的方法 1.1
TRACE 回显服务器收到的请求(用于测试) 1.1
经典面试题:GET vs POST 区别
维度 GET POST
语义 获取资源 提交资源
数据位置 数据通过 URL 的查询字符串传递 数据通过请求正文(Body)传递
数据可见性 数据暴露在 URL 中,不安全 数据在正文,相对安全(仍需加密)
幂等性
缓存 可被浏览器缓存(如静态资源) 不可缓存
数据大小 无标准限制,取决于浏览器/服务器实现(通常支持较大长度) 无标准限制,取决于服务器实现

注意

  • 安全性:POST 并非"绝对安全",若不加密(如 HTTP),正文数据仍可被劫持;
  • 数据类型:GET 可通过 URL Encode 传输二进制数据,POST 也可传输文本数据,无本质限制。

3.3 HTTP 状态码

状态码表示服务器对请求的处理结果,分为 5 大类,常见状态码及含义如下:

类别 范围 含义 常见状态码及说明
1XX 100-199 信息性响应 100 Continue:客户端需继续发送请求正文
2XX 200-299 成功 200 OK:请求成功 204 No Content:请求成功但无正文
3XX 300-399 重定向 301 Moved Permanently:永久重定向(如域名变更) 302 Found:临时重定向(如登录后跳转)
4XX 400-499 客户端错误 400 Bad Request:请求参数错误 403 Forbidden:访问被拒绝(如未登录) 404 Not Found:资源不存在
5XX 500-599 服务器错误 500 Internal Server Error:服务器代码异常 504 Gateway Timeout:服务器超时(如秒杀场景)

四、构造 HTTP 请求的 4 种方式

实际开发中,可通过浏览器、表单、Ajax、代码等多种方式构造 HTTP 请求,以下为具体实现。

4.1 浏览器地址栏:简单 GET 请求

直接输入 URL 并回车,浏览器自动发送 GET 请求,例如:

复制代码
https://www.sogou.com/?query=HTTP

4.2 HTML Form 表单:GET/POST 请求

Form 标签是前端提交数据的基础方式,支持 GET 和 POST 方法。

示例 1:Form 发送 GET 请求
html 复制代码
<!-- 提交后 URL 会拼接 query string:http://abcdef.com/myPath?userId=100&classId=200 -->
<form action="http://abcdef.com/myPath" method="GET">
	 <input type="text" name="userId">
	 <input type="text" name="classId">
	 <input type="submit" value="提交">
</form>

如图

示例 2:Form 发送 POST 请求
html 复制代码
<!-- 数据通过 Body 传递,URL 无 query string -->
<form action="http://abcdef.com/myPath" method="POST">
    <input type="text" name="username" placeholder="用户名">
    <input type="password" name="password" placeholder="密码">
    <input type="submit" value="登录">
</form>

4.3 Ajax:异步请求(无页面刷新)

Ajax(Asynchronous JavaScript and XML)是前端异步通信的核心技术,支持所有 HTTP 方法,且无需刷新页面。以下使用 jQuery 实现(简化原生 Ajax 复杂度)。

示例 1:Ajax 发送 GET 请求
html 复制代码
<!-- 引入 jQuery -->
<script src="https://code.jquery.com/jquery-3.6.3.min.js"></script>
<script>
$.ajax({
    type: 'GET',          // 方法
    url: 'https://www.sogou.com/?query=Ajax',  // 请求 URL
    success: function(data) {
        // 响应成功回调,data 为响应正文
        console.log("响应内容:", data);
    },
    error: function(xhr) {
        // 响应失败回调
        console.log("请求失败,状态码:", xhr.status);
    }
});
</script>

浏览器和服务器交互过程(引⼊ajax后):

示例 2:Ajax 发送 POST 请求(JSON 格式)
html 复制代码
<script src="https://code.jquery.com/jquery-3.6.3.min.js"></script>
<script>
$.ajax({
    type: 'POST',
    url: 'https://v.bitedu.vip/tms/login',
    contentType: 'application/json',  // 正文格式为 JSON
    data: JSON.stringify({            // 正文数据(需转为 JSON 字符串)
        username: '123456789',
        password: 'xxxx',
        code: 'jw7l'
    }),
    success: function(data) {
        console.log("登录成功:", data);
    }
});
</script>

4.4 Java Socket:底层代码构造请求

HTTP 请求本质是"符合协议格式的字符串",可通过 Java Socket 直接写入 TCP 流实现。

示例:Java 实现 HTTP 客户端
java 复制代码
import java.io.*;
import java.net.Socket;

public class HttpClient {
    private Socket socket;
    private String ip;
    private int port;

    // 初始化 Socket 连接
    public HttpClient(String ip, int port) throws IOException {
        this.ip = ip;
        this.port = port;
        this.socket = new Socket(ip, port);
    }

    // 发送 GET 请求
    public String get(String url) throws IOException {
        StringBuilder request = new StringBuilder();
        // 1. 构造首行
        request.append("GET " + url + " HTTP/1.1\n");
        // 2. 构造报头
        request.append("Host: " + ip + ":" + port + "\n");
        // 3. 空行(报头与正文分隔)
        request.append("\n");

        // 发送请求
        OutputStream os = socket.getOutputStream();
        os.write(request.toString().getBytes("UTF-8"));
        os.flush();

        // 读取响应
        InputStream is = socket.getInputStream();
        byte[] buffer = new byte[1024 * 1024];  // 1MB 缓冲区
        int len = is.read(buffer);
        return new String(buffer, 0, len, "UTF-8");
    }

    // 发送 POST 请求
    public String post(String url, String body) throws IOException {
        StringBuilder request = new StringBuilder();
        // 1. 首行
        request.append("POST " + url + " HTTP/1.1\n");
        // 2. 报头(需指定 Content-Length 和 Content-Type)
        request.append("Host: " + ip + ":" + port + "\n");
        request.append("Content-Length: " + body.getBytes().length + "\n");
        request.append("Content-Type: application/json\n");
        // 3. 空行
        request.append("\n");
        // 4. 正文
        request.append(body);

        // 发送请求
        OutputStream os = socket.getOutputStream();
        os.write(request.toString().getBytes("UTF-8"));
        os.flush();

        // 读取响应
        InputStream is = socket.getInputStream();
        byte[] buffer = new byte[1024 * 1024];
        int len = is.read(buffer);
        return new String(buffer, 0, len, "UTF-8");
    }

    // 测试:访问搜狗主页
    public static void main(String[] args) throws IOException {
        HttpClient client = new HttpClient("www.sogou.com", 80);
        // 发送 GET 请求
        String getResp = client.get("/");
        System.out.println("GET 响应:\n" + getResp);

        // 发送 POST 请求(示例,实际需符合搜狗接口格式)
        String postBody = "{\"query\":\"Java\"}";
        String postResp = client.post("/websearch/api/get", postBody);
        System.out.println("POST 响应:\n" + postResp);

        // 关闭连接
        client.socket.close();
    }
}

五、HTTPS:HTTP 的安全加密版

HTTP 存在明文传输 的缺陷------数据在网络中传输时,可被运营商、黑客劫持篡改(如"运营商劫持下载链接")。HTTPS 通过引入加密层(TLS/SSL) 解决这一问题,本质是"HTTP + TLS/SSL"。

臭名昭著的"运营商劫持"

下载⼀个天天动听

未被劫持的效果,点击下载按钮,就会弹出天天动听的下载链接.

已被劫持的效果,点击下载按钮,就会弹出QQ浏览器的下载链接

由于我们通过⽹络传输的任何的数据包都会经过运营商的⽹络设备(路由器,交换机等),那么运营商的网络设备就可以解析出你传输的数据内容,并进行篡改.
点击"下载按钮",其实就是在给服务器发送了⼀个HTTP请求,获取到的HTTP响应其实就包含了该APP的下载链接.运营商劫持之后,就发现这个请求是要下载天天动听,那么就⾃动的把交给用户的响应给篡改成"QQ浏览器"的下载地址了.


自然运营商进行劫持的目的也不言而喻啦$💴:(

5.1 HTTPS 的核心目标

  1. 机密性:数据传输过程中加密,防止被窃取;
  2. 完整性:数据不被篡改(如运营商替换下载链接);
  3. 身份认证:确认服务器身份,防止钓鱼网站。

5.2 加密算法基础

HTTPS 结合了对称加密非对称加密的优势,先了解两种加密的区别:

加密类型 密钥数量 速度 安全性 适用场景
对称加密 1 个(客户端和服务器共用) 快(适合大量数据) 中(密钥需安全传输) 后续数据传输(如 HTML、JSON)
非对称加密 2 个(公钥 + 私钥,配对使用) 慢(适合少量数据) 高(公钥可公开,私钥保密) 密钥协商(传输对称加密的密钥)


非对称加密的核心规则
  • 公钥加密的数据,仅能通过对应的私钥解密;
  • 私钥加密的数据,仅能通过对应的公钥解密。

5.3 HTTPS 完整工作流程

HTTPS 的核心是"安全协商对称密钥",流程分为 4 步,涉及 3 组密钥:

mindmap 复制代码
## HTTPS 工作流程
- 1. 客户端请求建立连接(Client Hello)
  - 发送支持的加密算法、TLS 版本
  - 生成随机数 R1
- 2. 服务器响应(Server Hello + 证书)
  - 选择加密算法、TLS 版本
  - 生成随机数 R2
  - 返回数字证书(含服务器公钥 Pub_S)
- 3. 客户端验证证书 + 协商对称密钥
  - 验证证书合法性(有效期、签名、域名)
  - 生成随机数 R3,用 Pub_S 加密后发送给服务器
  - 客户端用 R1+R2+R3 生成对称密钥 K
- 4. 服务器生成对称密钥 + 加密传输
  - 用私钥 Pri_S 解密获取 R3
  - 服务器用 R1+R2+R3 生成对称密钥 K
  - 后续数据用 K 对称加密传输
关键细节:证书与身份认证

证书是防止"中间人攻击"的核心,由第三方权威机构(CA,如 VeriSign、Let's Encrypt)颁发,包含以下信息:

  • 证书所有者(服务器域名、机构)
  • 服务器公钥 Pub_S
  • CA 签名(用 CA 私钥加密的证书摘要)
  • 有效期

引入证书

客户端验证证书的流程:

  1. 检查证书是否在有效期内
  2. 检查证书发布机构是否在操作系统/浏览器的"受信任 CA 列表"中
  3. 用 CA 公钥(系统内置)解密签名,获取证书摘要 H1
  4. 计算当前证书的摘要 H2,对比 H1 和 H2,确认证书未被篡改

5.4 HTTPS vs HTTP 对比

维度 HTTP HTTPS
端口 80 443
加密 明文传输,无加密 基于 TLS/SSL 加密
安全性 低(易被劫持、篡改) 高(机密性、完整性、身份认证)
性能 无额外开销,速度快 握手阶段需加密计算,速度略慢(可通过 TLS 复用优化)
证书 无需证书 需 CA 颁发证书(免费/付费)

六、总结

HTTP/HTTPS 是网络通信的基石,本文从基础到深入,覆盖了:

  1. HTTP 定位:应用层协议,依赖 TCP 传输;
  2. 协议格式:请求/响应均为"首行 + 报头 + 空行 + 正文";
  3. 核心概念:URL、方法、状态码的含义与使用场景;
  4. 请求构造:浏览器、Form、Ajax、Java Socket 四种方式;
  5. HTTPS 安全:结合对称/非对称加密,通过证书保障身份认证与数据安全。

掌握这些知识,不仅能应对面试,更能在实际开发中快速定位网络问题(如 404 资源缺失、HTTPS 证书错误),理解前后端通信的底层逻辑。

相关推荐
凡间客5 小时前
5、Python3编程之面向对象
java·服务器·数据库
我命由我123455 小时前
Spring Cloud - Spring Cloud 负载均衡(Ribbon 负载均衡概述、Ribbon 使用)
java·后端·spring·spring cloud·ribbon·java-ee·负载均衡
酷柚易汛智推官5 小时前
基于MemU的自主代理记忆管理系统:技术解析与实践
java·安全·架构
今禾5 小时前
流式输出深度解析:从应用层到传输层的完整技术剖析
前端·http·面试
曦樂~5 小时前
【Qt】TCP连接--客户端和服务器
服务器·网络·c++·qt·tcp/ip
TG_yunshuguoji5 小时前
阿里云代理商:如何给阿里云配置网络ACL?
服务器·网络·阿里云·云计算
懒鸟一枚5 小时前
Java 常见加密算法用法详解
java·开发语言
一念&5 小时前
每日一个网络知识点:应用层WWW与HTTP
网络·网络协议·http
oak隔壁找我5 小时前
SpringBoot 开发必备基础工具类实现(纯JWT认证,无SpringSecurity)
java·后端