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 请求/响应的交互,以搜狗搜索为例:
- 客户端(浏览器)输入 URL(如
https://www.sogou.com
),向搜狗服务器发送 HTTP 请求; - 服务器接收请求,处理后返回 HTTP 响应(包含 HTML 页面、CSS、JavaScript 等资源信息);
- 浏览器解析响应内容,渲染成用户看到的页面(过程中可能触发多次请求,如加载图片、字体)。
通过 Chrome 开发者工具(F12 → Network 标签)可观察详细请求过程,每一条记录都是一次完整的“请求-响应”:
(实际使用时可自行打开搜狗主页查看)
二、HTTP 协议格式:请求与响应的结构
HTTP 是文本格式协议,请求和响应均由“首行 + 报头 + 空行 + 正文”四部分组成。通过 Fiddler 或 Chrome 抓包可直观看到格式细节。
2.1 HTTP 请求格式
请求报文的结构如下,以“西安交大就业网登录”的 POST 请求为例:
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=1506661802username=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/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 请求
<!-- 提交后 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 请求
<!-- 数据通过 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 请求
<!-- 引入 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', // 请求 URLsuccess: function(data) {// 响应成功回调,data 为响应正文console.log("响应内容:", data);},error: function(xhr) {// 响应失败回调console.log("请求失败,状态码:", xhr.status);}
});
</script>
浏览器和服务器交互过程(引⼊ajax后):
示例 2:Ajax 发送 POST 请求(JSON 格式)
<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', // 正文格式为 JSONdata: 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 客户端
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 的核心目标
- 机密性:数据传输过程中加密,防止被窃取;
- 完整性:数据不被篡改(如运营商替换下载链接);
- 身份认证:确认服务器身份,防止钓鱼网站。
5.2 加密算法基础
HTTPS 结合了对称加密和非对称加密的优势,先了解两种加密的区别:
加密类型 | 密钥数量 | 速度 | 安全性 | 适用场景 |
---|---|---|---|---|
对称加密 | 1 个(客户端和服务器共用) | 快(适合大量数据) | 中(密钥需安全传输) | 后续数据传输(如 HTML、JSON) |
非对称加密 | 2 个(公钥 + 私钥,配对使用) | 慢(适合少量数据) | 高(公钥可公开,私钥保密) | 密钥协商(传输对称加密的密钥) |
非对称加密的核心规则
- 公钥加密的数据,仅能通过对应的私钥解密;
- 私钥加密的数据,仅能通过对应的公钥解密。
5.3 HTTPS 完整工作流程
HTTPS 的核心是“安全协商对称密钥”,流程分为 4 步,涉及 3 组密钥:
## 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 私钥加密的证书摘要)
- 有效期
引入证书
客户端验证证书的流程:
- 检查证书是否在有效期内
- 检查证书发布机构是否在操作系统/浏览器的“受信任 CA 列表”中
- 用 CA 公钥(系统内置)解密签名,获取证书摘要 H1
- 计算当前证书的摘要 H2,对比 H1 和 H2,确认证书未被篡改
5.4 HTTPS vs HTTP 对比
维度 | HTTP | HTTPS |
---|---|---|
端口 | 80 | 443 |
加密 | 明文传输,无加密 | 基于 TLS/SSL 加密 |
安全性 | 低(易被劫持、篡改) | 高(机密性、完整性、身份认证) |
性能 | 无额外开销,速度快 | 握手阶段需加密计算,速度略慢(可通过 TLS 复用优化) |
证书 | 无需证书 | 需 CA 颁发证书(免费/付费) |
六、总结
HTTP/HTTPS 是网络通信的基石,本文从基础到深入,覆盖了:
- HTTP 定位:应用层协议,依赖 TCP 传输;
- 协议格式:请求/响应均为“首行 + 报头 + 空行 + 正文”;
- 核心概念:URL、方法、状态码的含义与使用场景;
- 请求构造:浏览器、Form、Ajax、Java Socket 四种方式;
- HTTPS 安全:结合对称/非对称加密,通过证书保障身份认证与数据安全。
掌握这些知识,不仅能应对面试,更能在实际开发中快速定位网络问题(如 404 资源缺失、HTTPS 证书错误),理解前后端通信的底层逻辑。