知识点编号:035
难度等级:⭐⭐(必掌握)
面试频率:🔥🔥🔥🔥🔥
🎯 一句话总结
HTTP就像快递服务,你发请求(下单),服务器送响应(送货),但它不记得你是谁!📦
🤔 HTTP是什么?
HTTP:HyperText Transfer Protocol
超文本传输协议
作用:
- Web浏览器和服务器之间的通信协议
- 传输HTML、图片、视频、JSON等数据
- 互联网的基础协议
生活比喻:
HTTP就像邮局的服务规则
- 你写信(HTTP请求)
- 邮局送信(HTTP响应)
- 每次都要写完整地址(无状态)
🎨 HTTP的核心特点
1. 无状态(Stateless)
定义:
服务器不保存客户端的历史请求信息
每个请求都是独立的
示例:
第1次请求:登录成功
第2次请求:访问个人页面
服务器不记得你已经登录了!
生活比喻:
你每次去餐厅
服务员都不记得你
每次都要重新点菜 🍽️
问题:
- 无法识别用户身份
- 无法保持登录状态
- 无法实现购物车
解决方案:
1. Cookie(客户端存储)
浏览器保存一个凭证
每次请求都带上
2. Session(服务器端存储)
服务器生成Session ID
客户端保存Session ID
3. Token(令牌)
服务器颁发Token
客户端每次请求携带Token
2. 请求-响应模型(Request-Response)
工作模式:
客户端主动发起请求
服务器被动响应
单向通信:
客户端 -----请求-----> 服务器
客户端 <----响应------ 服务器
特点:
✅ 客户端主动,服务器被动
✅ 一个请求对应一个响应
✅ 服务器不能主动推送(HTTP/1.x)
❌ 无法实时通信(需要轮询或WebSocket)
示例:
// 请求
GET /api/user/123 HTTP/1.1
Host: www.example.com
// 响应
HTTP/1.1 200 OK
Content-Type: application/json
{"id":123,"name":"张三"}
3. 基于TCP协议
HTTP工作在应用层
基于TCP传输层协议
层次结构:
应用层:HTTP
传输层:TCP
网络层:IP
数据链路层:以太网
为什么使用TCP?
✅ 可靠传输(保证数据完整)
✅ 有序传输(数据顺序正确)
✅ 错误检测和重传
❌ 慢启动(性能影响)
HTTP/1.x和HTTP/2:基于TCP
HTTP/3:基于QUIC(UDP之上)
4. 灵活可扩展
支持多种内容类型:
- text/html(HTML网页)
- text/plain(纯文本)
- application/json(JSON数据)
- image/jpeg(图片)
- video/mp4(视频)
- application/pdf(PDF文档)
支持多种编码:
- gzip(压缩)
- deflate(压缩)
- br(Brotli压缩)
支持多种语言:
- zh-CN(简体中文)
- en-US(英语)
- ja-JP(日语)
支持自定义头部:
X-Custom-Header: value
X-Request-ID: 12345
5. 明文传输(不安全)
问题:
HTTP传输的数据是明文
任何人都可以截获和查看
风险:
🔓 密码泄露
🔓 隐私泄露
🔓 数据被篡改
解决:
使用HTTPS(HTTP + SSL/TLS)
🔒 加密传输
🔒 身份验证
🔒 数据完整性
📊 HTTP通信过程
完整流程:
1. 建立TCP连接
客户端 ←→ 服务器(三次握手)
2. 发送HTTP请求
GET /index.html HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0
3. 服务器处理请求
- 解析请求
- 查找资源
- 生成响应
4. 发送HTTP响应
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 1234
<!DOCTYPE html>...
5. 关闭连接(或保持连接)
- 短连接:立即关闭(四次挥手)
- 长连接:保持一段时间(Keep-Alive)
💻 Java代码示例
import java.net.*;
import java.io.*;
public class HTTPExample {
/**
* 简单的HTTP GET请求
*/
public static String httpGet(String urlString) throws Exception {
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// 设置请求方法
conn.setRequestMethod("GET");
// 设置请求头
conn.setRequestProperty("User-Agent", "Mozilla/5.0");
conn.setRequestProperty("Accept", "text/html");
// 连接超时和读取超时
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
// 发送请求,获取响应
int responseCode = conn.getResponseCode();
System.out.println("响应码: " + responseCode);
// 读取响应
BufferedReader reader = new BufferedReader(
new InputStreamReader(conn.getInputStream(), "UTF-8")
);
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line).append("\n");
}
reader.close();
conn.disconnect();
return response.toString();
}
/**
* HTTP POST请求
*/
public static String httpPost(String urlString, String jsonData)
throws Exception {
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// 设置请求方法
conn.setRequestMethod("POST");
// 设置请求头
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Accept", "application/json");
// 允许输出
conn.setDoOutput(true);
// 写入请求体
OutputStream os = conn.getOutputStream();
os.write(jsonData.getBytes("UTF-8"));
os.flush();
os.close();
// 获取响应
int responseCode = conn.getResponseCode();
System.out.println("响应码: " + responseCode);
BufferedReader reader = new BufferedReader(
new InputStreamReader(conn.getInputStream(), "UTF-8")
);
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line).append("\n");
}
reader.close();
conn.disconnect();
return response.toString();
}
/**
* 完整的HTTP请求示例
*/
public static void fullHTTPExample() {
try {
String url = "https://api.github.com/users/github";
System.out.println("=== HTTP GET示例 ===\n");
System.out.println("请求URL: " + url);
// 创建连接
HttpURLConnection conn = (HttpURLConnection)
new URL(url).openConnection();
// 设置请求属性
conn.setRequestMethod("GET");
conn.setRequestProperty("User-Agent", "Java-HTTP-Client");
// 发送请求
System.out.println("\n发送HTTP请求...");
int responseCode = conn.getResponseCode();
String responseMessage = conn.getResponseMessage();
System.out.println("\n=== 响应信息 ===");
System.out.println("状态码: " + responseCode);
System.out.println("状态消息: " + responseMessage);
// 打印响应头
System.out.println("\n=== 响应头 ===");
conn.getHeaderFields().forEach((key, values) -> {
if (key != null) {
System.out.println(key + ": " +
String.join(", ", values));
}
});
// 读取响应体
if (responseCode == 200) {
System.out.println("\n=== 响应体 ===");
BufferedReader reader = new BufferedReader(
new InputStreamReader(conn.getInputStream())
);
String line;
StringBuilder response = new StringBuilder();
while ((line = reader.readLine()) != null) {
response.append(line).append("\n");
}
reader.close();
System.out.println(response.toString());
}
conn.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 演示无状态特性
*/
public static void demonstrateStateless() {
System.out.println("=== 演示HTTP无状态特性 ===\n");
try {
String url = "https://httpbin.org/get";
// 第1次请求
System.out.println("第1次请求:");
HttpURLConnection conn1 = (HttpURLConnection)
new URL(url).openConnection();
conn1.setRequestMethod("GET");
System.out.println("响应码: " + conn1.getResponseCode());
conn1.disconnect();
// 第2次请求
System.out.println("\n第2次请求:");
HttpURLConnection conn2 = (HttpURLConnection)
new URL(url).openConnection();
conn2.setRequestMethod("GET");
System.out.println("响应码: " + conn2.getResponseCode());
conn2.disconnect();
System.out.println("\n每次请求都是独立的,服务器不记得之前的请求!");
System.out.println("这就是HTTP的无状态特性。");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// 完整示例
fullHTTPExample();
System.out.println("\n" + "=".repeat(60) + "\n");
// 演示无状态
demonstrateStateless();
}
}
🐛 常见面试题
Q1:HTTP协议有哪些主要特点?
答案:
HTTP的5大特点:
1. 无状态(Stateless) 🔄
- 服务器不保存客户端状态
- 每个请求都是独立的
- 优点:简单、可扩展
- 缺点:无法识别用户
- 解决:Cookie、Session、Token
2. 请求-响应模型(Request-Response) 🔄
- 客户端主动发起请求
- 服务器被动响应
- 一问一答模式
- 服务器不能主动推送
3. 基于TCP协议 🔧
- 可靠传输
- 有序传输
- 面向连接
- HTTP/3改用QUIC(基于UDP)
4. 灵活可扩展 🎨
- 支持多种内容类型
- 支持自定义头部
- 版本升级(1.0→1.1→2.0→3.0)
5. 明文传输(不安全) 🔓
- 数据未加密
- 容易被窃听和篡改
- 解决:使用HTTPS
Q2:HTTP为什么是无状态的?无状态有什么优缺点?
答案:
无状态的含义:
服务器不保存客户端的历史请求信息
每个请求都是独立的,互不影响
优点:
1. 简单 ✅
- 服务器不需要记录状态
- 实现简单,易于理解
2. 可扩展 ✅
- 每个请求独立
- 可以由任意服务器处理
- 容易实现负载均衡
3. 可靠 ✅
- 不怕状态丢失
- 服务器崩溃不影响客户端
4. 性能 ✅
- 不需要维护状态
- 减少服务器内存开销
缺点:
1. 无法识别用户 ❌
- 不知道请求来自谁
- 需要额外机制(Cookie/Session)
2. 无法保持会话 ❌
- 无法记住登录状态
- 每次都要传递身份信息
3. 数据冗余 ❌
- 每次请求都要带完整信息
- 增加流量消耗
解决方案:
1. Cookie
- 客户端存储
- 自动发送
2. Session
- 服务器端存储
- 通过Session ID关联
3. Token(JWT)
- 自包含信息
- 无需服务器存储
4. LocalStorage/SessionStorage
- 浏览器本地存储
- 容量更大
🎓 总结
HTTP协议的关键点:
- 无状态:不记录历史
- 请求-响应:一问一答
- 基于TCP:可靠传输
- 明文传输:不安全(用HTTPS)
记忆口诀:
HTTP请求响应 🔄
无状态不记忆 🧠
基于TCP可靠 🔗
明文需要加密 🔒
文档创建时间:2025-10-31