文章目录
-
- HTTP协议深度解析(二):方法、状态码与Header详解
- 一、HTTP方法详解
-
- [1.1 方法的作用](#1.1 方法的作用)
- [1.2 GET方法(重点)](#1.2 GET方法(重点))
-
- [1.2.1 GET请求的应用场景](#1.2.1 GET请求的应用场景)
- [1.3 POST方法(重点)](#1.3 POST方法(重点))
-
- [1.3.1 POST请求的应用场景](#1.3.1 POST请求的应用场景)
- [1.4 GET vs POST(面试常考)](#1.4 GET vs POST(面试常考))
- [1.5 HEAD方法](#1.5 HEAD方法)
-
- [1.5.1 HEAD的应用场景](#1.5.1 HEAD的应用场景)
- [1.6 PUT方法](#1.6 PUT方法)
- [1.7 DELETE方法](#1.7 DELETE方法)
- [1.8 OPTIONS方法](#1.8 OPTIONS方法)
- 二、HTML表单与HTTP的关系
-
- [2.1 什么是HTML表单](#2.1 什么是HTML表单)
- [2.2 GET表单](#2.2 GET表单)
- [2.3 POST表单](#2.3 POST表单)
- [2.4 Content-Type详解](#2.4 Content-Type详解)
-
- [2.4.1 application/x-www-form-urlencoded(默认)](#2.4.1 application/x-www-form-urlencoded(默认))
- [2.4.2 multipart/form-data(文件上传)](#2.4.2 multipart/form-data(文件上传))
- [2.4.3 application/json](#2.4.3 application/json)
- 三、HTTP状态码详解
-
- [3.1 状态码分类](#3.1 状态码分类)
- [3.2 1xx信息性状态码](#3.2 1xx信息性状态码)
- [3.3 2xx成功状态码](#3.3 2xx成功状态码)
-
- [3.3.1 200 OK](#3.3.1 200 OK)
- [3.3.2 201 Created](#3.3.2 201 Created)
- [3.3.3 204 No Content](#3.3.3 204 No Content)
- [3.4 3xx重定向状态码](#3.4 3xx重定向状态码)
-
- [3.4.1 301永久重定向](#3.4.1 301永久重定向)
- [3.4.2 302临时重定向](#3.4.2 302临时重定向)
- [3.4.3 304未修改](#3.4.3 304未修改)
- [3.5 4xx客户端错误状态码](#3.5 4xx客户端错误状态码)
-
- [3.5.1 /api/login HTTP/1.1](#3.5.1 /api/login HTTP/1.1)
- [3.5.2 401 Unauthorized](#3.5.2 401 Unauthorized)
- [3.5.3 403 Forbidden](#3.5.3 403 Forbidden)
- [3.5.4 404 Not Found](#3.5.4 404 Not Found)
- [3.6 5xx服务器错误状态码](#3.6 5xx服务器错误状态码)
-
- [3.6.1 500 Internal Server Error](#3.6.1 500 Internal Server Error)
- [3.6.2 502 Bad Gateway](#3.6.2 502 Bad Gateway)
- [3.6.3 503 Service Unavailable](#3.6.3 503 Service Unavailable)
- 四、重定向原理深度剖析
-
- [4.1 重定向的工作流程](#4.1 重定向的工作流程)
- [4.2 Location字段](#4.2 Location字段)
- [4.3 301 vs 302的区别](#4.3 301 vs 302的区别)
- [4.4 验证重定向](#4.4 验证重定向)
- 五、常见Header详解
-
- [5.1 Content-Type](#5.1 Content-Type)
- [5.2 Content-Length](#5.2 Content-Length)
- [5.3 Host](#5.3 Host)
- [5.4 User-Agent](#5.4 User-Agent)
- [5.5 User-Agent的历史故事](#5.5 User-Agent的历史故事)
- [5.6 Cookie](#5.6 Cookie)
- [5.7 Referer](#5.7 Referer)
- [5.8 Accept系列](#5.8 Accept系列)
- 六、本篇总结
-
- [6.1 核心要点](#6.1 核心要点)
- [6.2 容易混淆的点](#6.2 容易混淆的点)
HTTP协议深度解析(二):方法、状态码与Header详解
💬 开篇:上一篇完成了HTTP协议的基础知识,包括URL详解、urlencode、请求响应格式,还用TCP Socket手写了一个最简单的HTTP服务器。但实际应用中,HTTP有多种方法(GET、POST、HEAD等),有丰富的状态码(200、404、302等),有各种各样的Header字段。这一篇深入讲解HTTP的方法、状态码和Header,包括它们的含义、使用场景、实际验证。理解了这些,就能处理各种复杂的HTTP应用场景,包括表单提交、文件上传、重定向、缓存控制等。
👍 点赞、收藏与分享:这篇会把HTTP方法、状态码、Header的核心知识讲透,每个知识点都有实际验证。如果对你有帮助,请点赞收藏!
🚀 循序渐进:从HTTP方法的分类开始,到GET和POST的详细对比,到HTML表单,到状态码详解,到重定向原理,到常见Header,一步步掌握HTTP的核心机制。
一、HTTP方法详解
1.1 方法的作用
HTTP方法(Method)也叫HTTP动词(Verb),用于告诉服务器客户端想要执行什么操作。
常见方法:
| 方法 | 含义 | 常用程度 |
|---|---|---|
| GET | 获取资源 | ⭐⭐⭐⭐⭐ |
| POST | 提交数据 | ⭐⭐⭐⭐⭐ |
| HEAD | 获取响应头 | ⭐⭐ |
| PUT | 更新资源 | ⭐⭐ |
| DELETE | 删除资源 | ⭐⭐ |
| OPTIONS | 查询支持的方法 | ⭐ |
| TRACE | 回显请求 | ⭐ |
| CONNECT | 建立隧道 | ⭐ |
最常用的是GET和POST,占据了99%以上的HTTP请求。
1.2 GET方法(重点)
用途:请求获取指定资源。
请求格式:
bash
GET /index.html HTTP/1.1
Host: [www.example.com](http://www.example.com)
特点:
- 参数在URL中(查询字符串)
- 浏览器会缓存GET请求
- 可以被收藏为书签
- 参数长度有限制(浏览器限制,通常2KB-8KB)
- 参数会显示在浏览器地址栏,不安全
示例:
bash
GET /search?keyword=Linux&page=2 HTTP/1.1
Host: [www.example.com](http://www.example.com)
服务器解析出:
- keyword = "Linux"
- page = "2"
1.2.1 GET请求的应用场景
- 浏览网页:访问网站首页、文章页面等
- 搜索:搜索引擎查询
- API查询:获取用户信息、商品列表等
- 图片/CSS/JS加载:浏览器加载静态资源
示例URL:
bash
[http://www.baidu.com/s?wd=Linux](http://www.baidu.com/s?wd=Linux) # 百度搜索
[http://www.example.com/api/users?id=123](http://www.example.com/api/users?id=123) # API查询
[http://www.example.com/images/logo.png](http://www.example.com/images/logo.png) # 加载图片
1.3 POST方法(重点)
用途:向服务器提交数据。
请求格式:
bash
POST /api/login HTTP/1.1
Host: [www.example.com](http://www.example.com)
Content-Type: application/x-www-form-urlencoded
Content-Length: 27
username=admin&password=123
特点:
- 参数在Body中(不在URL中)
- 浏览器一般不缓存POST请求
- 不能被收藏为书签
- 参数长度理论上无限制(实际受服务器限制)
- 参数不显示在地址栏,相对安全
- 可以传输大量数据(文件上传等)
1.3.1 POST请求的应用场景
- 表单提交:登录、注册、评论等
- 文件上传:上传图片、视频等
- API操作:创建用户、修改数据等
- 数据提交:提交订单、发送消息等
示例:
bash
POST /api/register HTTP/1.1
Host: [www.example.com](http://www.example.com)
Content-Type: application/x-www-form-urlencoded
Content-Length: 50
username=zhangsan&password=123456&email=[test@qq.com](mailto:test@qq.com)
1.4 GET vs POST(面试常考)
| 对比项 | GET | POST |
|---|---|---|
| 参数位置 | URL查询字符串 | Body中 |
| 参数长度 | 有限制(2KB-8KB) | 理论无限制 |
| 安全性 | 参数暴露在URL | 相对安全 |
| 缓存 | 会被缓存 | 一般不会被缓存 |
| 书签 | 可以收藏 | 不能收藏 |
| 后退/刷新 | 无影响 | 数据会重新提交 |
| 语义 | 获取资源 | 提交数据 |
| 幂等性 | 幂等(多次请求结果相同) | 非幂等 |
幂等性的例子:
bash
GET /api/users?id=123 # 多次请求,返回同样的用户信息(幂等)
POST /api/orders # 多次请求,会创建多个订单(非幂等)
重要误区:
- GET也可以有Body,POST也可以有查询参数,但不推荐
- "GET不安全,POST安全"是错的,都是明文传输(除非用HTTPS)
- GET的参数长度限制是浏览器限制,不是HTTP协议限制
1.5 HEAD方法
用途:获取响应头,不返回Body。
请求格式:
bash
HEAD /index.html HTTP/1.1
Host: [www.example.com](http://www.example.com)
响应:
bash
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 1024
Last-Modified: Wed, 21 Oct 2023 07:20:00 GMT
(没有Body)
1.5.1 HEAD的应用场景
- 检查资源是否存在:不下载内容,只看状态码
- 获取资源元信息:文件大小、修改时间等
- 检查资源是否更新:通过Last-Modified判断
curl测试:
bash
# HEAD请求
curl --head http://www.baidu.com
# 输出(只有响应头,没有Body)
HTTP/1.1 200 OK
Server: bfe/1.0.8.18
Date: Wed, 21 Oct 2023 07:28:00 GMT
Content-Type: text/html
Content-Length: 2381
...
1.6 PUT方法
用途:更新资源。
请求格式:
bash
PUT /api/users/123 HTTP/1.1
Host: www.example.com
Content-Type: application/json
Content-Length: 45
{"name":"张三","age":30,"city":"北京"}
特点:
- 用于更新已存在的资源
- 如果资源不存在,可能创建新资源(取决于服务器实现)
- RESTful API常用
PUT vs POST:
- PUT是幂等的(多次更新,结果相同)
- POST是非幂等的(多次提交,可能创建多个资源)
POST:向集合资源创建子资源(服务器分配 URI)
PUT:对指定 URI 的资源整体替换/创建(客户端知道 URI)
1.7 DELETE方法
用途:删除资源。
请求格式:
bash
DELETE /api/users/123 HTTP/1.1
Host: www.example.com
特点:
- 删除指定资源
- RESTful API常用
- 幂等(多次删除同一个资源,结果相同)
1.8 OPTIONS方法
用途:查询服务器支持哪些 HTTP 方法。
请求格式:
bash
OPTIONS /api/users HTTP/1.1
Host: www.example.com
响应:
bash
HTTP/1.1 200 OK
Allow: GET, POST, PUT, DELETE, OPTIONS
Content-Length: 0
应用场景:
- CORS跨域请求的预检(Preflight),预检请求一般是:OPTIONS + Origin + Access-Control-Request-Method/Headers,响应要带:Access-Control-Allow-Origin/Methods/Headers
- 检查API支持哪些操作
curl测试:
bash
curl -X OPTIONS http://127.0.0.1/
# 如果服务器不支持OPTIONS
HTTP/1.1 405 Not Allowed
Content-Type: text/html
Content-Length: 166
<html>
<head><title>405 Not Allowed</title></head>
<body>
<center><h1>405 Not Allowed</h1></center>
</body>
</html>
二、HTML表单与HTTP的关系
2.1 什么是HTML表单
HTML表单(Form)是网页中收集用户输入的主要方式。
基本结构:
html
<form action="/api/login" method="POST">
<input type="text" name="username" placeholder="用户名">
<input type="password" name="password" placeholder="密码">
<button type="submit">登录</button>
</form>
关键属性:
action:表单提交的URLmethod:HTTP方法(GET或POST)
2.2 GET表单
html
<form action="/search" method="GET">
<input type="text" name="keyword" placeholder="搜索关键词">
<input type="number" name="page" value="1">
<button type="submit">搜索</button>
</form>
用户输入"Linux",点击提交,浏览器发送:
bash
GET /search?keyword=Linux&page=1 HTTP/1.1
Host: www.example.com
特点:参数拼接到URL后面。
2.3 POST表单
html
<form action="/api/login" method="POST">
<input type="text" name="username" placeholder="用户名">
<input type="password" name="password" placeholder="密码">
<button type="submit">登录</button>
</form>
用户输入用户名"admin",密码"123",点击提交,浏览器发送:
bash
POST /api/login HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 27
username=admin&password=123
特点 :参数在Body中,格式是key1=value1&key2=value2。
2.4 Content-Type详解
POST表单的Content-Type有多种:
2.4.1 application/x-www-form-urlencoded(默认)
格式:键值对,&分隔,和URL查询参数相同。
bash
Content-Type: application/x-www-form-urlencoded
username=admin&password=123&email=test%40qq.com
特殊字符需要urlencode(如@变成%40)。
2.4.2 multipart/form-data(文件上传)
用途:上传文件。
html
<form action="/upload" method="POST" enctype="multipart/form-data">
<input type="file" name="avatar">
<button type="submit">上传</button>
</form>
请求:
bash
POST /upload HTTP/1.1
Host: www.example.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Length: 234
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="avatar"; filename="photo.jpg"
Content-Type: image/jpeg
(二进制图片数据)
------WebKitFormBoundary7MA4YWxkTrZu0gW--
boundary是分隔符,每个字段用boundary分隔。
2.4.3 application/json
用途:提交JSON数据(现代Web API常用)。
javascript
fetch('/api/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
username: 'admin',
password: '123'
})
});
请求:
bash
POST /api/login HTTP/1.1
Host: www.example.com
Content-Type: application/json
Content-Length: 45
{"username":"admin","password":"123"}
三、HTTP状态码详解
3.1 状态码分类
HTTP状态码是三位数字,表示请求的处理结果。
| 分类 | 范围 | 含义 |
|---|---|---|
| 1xx | 100-199 | 信息性状态码(请求正在处理) |
| 2xx | 200-299 | 成功状态码(请求成功) |
| 3xx | 300-399 | 重定向状态码(需要进一步操作) |
| 4xx | 400-499 | 客户端错误状态码 |
| 5xx | 500-599 | 服务器错误状态码 |
3.2 1xx信息性状态码
| 状态码 | 含义 | 应用场景 |
|---|---|---|
| 100 Continue | 继续 | 上传大文件时,服务器告诉客户端可以继续上传 |
100 Continue的使用:
bash
客户端先发送请求头:
POST /upload HTTP/1.1
Host: www.example.com
Content-Length: 104857600
Expect: 100-continue
服务器返回:
HTTP/1.1 100 Continue
客户端继续发送Body(100MB的文件数据)
避免客户端发送大量数据后才发现服务器不接受请求。
3.3 2xx成功状态码
| 状态码 | 含义 | 应用场景 |
|---|---|---|
| 200 OK | 成功 | 访问网页、API查询成功 |
| 201 Created | 已创建 | POST创建资源成功 |
| 204 No Content | 无内容 | DELETE成功,不返回内容 |
3.3.1 200 OK
最常见的状态码,表示请求成功。
bash
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 1024
<html>...</html>
3.3.2 201 Created
表示资源创建成功。
bash
POST /api/articles HTTP/1.1
Content-Type: application/json
{"title":"新文章","content":"内容"}
响应:
HTTP/1.1 201 Created
Location: /api/articles/123
Content-Type: application/json
{"id":123,"title":"新文章","content":"内容"}
Location字段指示新资源的URL。
3.3.3 204 No Content
表示成功,但没有返回内容。
bash
DELETE /api/articles/123 HTTP/1.1
响应:
HTTP/1.1 204 No Content
Content-Length: 0
3.4 3xx重定向状态码
| 状态码 | 含义 | 是否永久 | 应用场景 |
|---|---|---|---|
| 301 Moved Permanently | 永久重定向 | 是 | 网站换域名 |
| 302 Found | 临时重定向 | 否 | 登录后跳转 |
| 304 Not Modified | 未修改 | - | 浏览器缓存 |
| 307 Temporary Redirect | 临时重定向 | 否 | 保持HTTP方法 |
| 308 Permanent Redirect | 永久重定向 | 是 | 保持HTTP方法 |
3.4.1 301永久重定向
表示资源已永久移动到新位置。
bash
GET /old-page HTTP/1.1
Host: www.example.com
响应:
HTTP/1.1 301 Moved Permanently
Location: http://www.example.com/new-page
Content-Length: 0
浏览器行为:
- 收到301响应
- 自动跳转到Location指定的URL
- 搜索引擎会更新索引(旧URL权重转移到新URL)
应用场景:
- 网站换域名:
http://old.com → http://new.com - HTTP升级HTTPS:
http://example.com → https://example.com
3.4.2 302临时重定向
表示资源临时移动到新位置。
bash
GET /login HTTP/1.1
Host: www.example.com
响应:
HTTP/1.1 302 Found
Location: http://www.example.com/dashboard
Content-Length: 0
浏览器行为:
- 收到302响应
- 自动跳转到Location指定的URL
- 搜索引擎不更新索引(保留原URL)
应用场景:
- 登录成功后跳转到首页
- 访问需要权限的页面时跳转到登录页
301:通常被当作永久迁移,搜索引擎更倾向转移权重
302:通常被当作临时迁移,搜索引擎更倾向保留原地址(但会根据长期行为调整)
3.4.3 304未修改
表示资源未修改,使用缓存版本。
bash
GET /style.css HTTP/1.1
Host: www.example.com
If-Modified-Since: Wed, 21 Oct 2023 07:20:00 GMT
响应:
HTTP/1.1 304 Not Modified
Last-Modified: Wed, 21 Oct 2023 07:20:00 GMT
Content-Length: 0
浏览器行为:
- 发送If-Modified-Since(上次缓存的修改时间)
- 服务器检查资源是否修改
- 未修改,返回304,浏览器使用缓存
- 已修改,返回200和新内容
优势:节省带宽,提高性能。
3.5 4xx客户端错误状态码
| 状态码 | 含义 | 应用场景 |
|---|---|---|
| 400 Bad Request | 请求错误 | 参数格式错误 |
| 401 Unauthorized | 未认证 | 未登录或token过期 |
| 403 Forbidden | 禁止访问 | 没有权限 |
| 404 Not Found | 未找到 | 资源不存在 |
3.5.1 /api/login HTTP/1.1
bash
POST /api/login HTTP/1.1
Host: www.example.com
Content-Type: application/json
Content-Length: ...
{invalid json}
3.5.2 401 Unauthorized
需要认证(登录)。
bash
GET /api/profile HTTP/1.1
响应:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer
{"error":"Authentication required"}
3.5.3 403 Forbidden
没有权限访问。
bash
GET /admin/users HTTP/1.1
Authorization: Bearer <user_token>
响应:
HTTP/1.1 403 Forbidden
{"error":"Admin access required"}
401 vs 403:
- 401:未登录,提供认证后可能访问
- 403:已登录,但权限不足,提供认证也无法访问
3.5.4 404 Not Found
资源不存在。
bash
GET /nonexistent-page HTTP/1.1
响应:
HTTP/1.1 404 Not Found
Content-Type: text/html
<html>
<body><h1>404 Not Found</h1></body>
</html>
3.6 5xx服务器错误状态码
| 状态码 | 含义 | 应用场景 |
|---|---|---|
| 500 Internal Server Error | 服务器内部错误 | 代码异常、崩溃 |
| 502 Bad Gateway | 网关错误 | 代理服务器无法连接上游服务器 |
| 503 Service Unavailable | 服务不可用 | 服务器维护或过载 |
| 504 Gateway Timeout | 网关超时 | 上游服务器响应超时 |
3.6.1 500 Internal Server Error
服务器内部错误(代码bug、数据库错误等)。
bash
GET /api/users HTTP/1.1
响应:
HTTP/1.1 500 Internal Server Error
Content-Type: text/html
<html>
<body><h1>500 Internal Server Error</h1></body>
</html>
3.6.2 502 Bad Gateway
代理服务器无法从上游服务器获取有效响应。
bash
架构:浏览器 → Nginx(代理) → 应用服务器
如果应用服务器挂了,Nginx返回:
HTTP/1.1 502 Bad Gateway
3.6.3 503 Service Unavailable
服务暂时不可用(维护、过载等)。
bash
HTTP/1.1 503 Service Unavailable
Retry-After: 3600
Content-Type: text/plain
Content-Length: 19
Service Unavailable
四、重定向原理深度剖析
4.1 重定向的工作流程
- 客户端请求 GET /old-page
- 服务器返回 301 + Location: /new-page
- 客户端自动请求 GET /new-page
- 服务器返回 200 + 页面内容(或 JSON 等响应体)。
4.2 Location字段
Location字段指定重定向的目标URL。
可以是相对路径或绝对路径:
bash
# 相对路径
Location: /new-page
# 绝对路径
Location: http://www.example.com/new-page
# 不同域名
Location: http://www.newdomain.com/page
4.3 301 vs 302的区别
| 对比项 | 301 | 302 |
|---|---|---|
| 含义 | 永久重定向 | 临时重定向 |
| 搜索引擎 | 更新索引,权重转移 | 保留原URL索引 |
| 浏览器缓存 | 可能缓存重定向 | 不缓存 |
| 应用场景 | 网站换域名、HTTP→HTTPS | 登录跳转、临时维护页面 |
例子:
网站换域名(用301):
bash
访问 http://old.com
返回:
HTTP/1.1 301 Moved Permanently
Location: http://new.com
浏览器自动跳转到 http://new.com
搜索引擎更新索引,old.com的权重转移到new.com
登录跳转(用302):
bash
访问 http://example.com/dashboard(需要登录)
返回:
HTTP/1.1 302 Found
Location: http://example.com/login
浏览器自动跳转到登录页
登录成功后,再跳转回dashboard
4.4 验证重定向
修改我们的HTTP服务器,添加重定向功能:
c
if (strstr(request, "GET /redirect") != NULL) {
const char* response =
"HTTP/1.1 302 Found\r\n"
"Location: http://www.baidu.com\r\n"
"Content-Length: 0\r\n"
"\r\n";
write(clientfd, response, strlen(response));
} else {
// 正常处理
}
浏览器访问http://127.0.0.1:9090/redirect,会自动跳转到百度首页。
五、常见Header详解
5.1 Content-Type
用途:指定Body的媒体类型(MIME类型)。
常见值:
| Content-Type | 含义 | 应用场景 |
|---|---|---|
| text/html | HTML页面 | 网页 |
| text/plain | 纯文本 | txt文件 |
| application/json | JSON数据 | API响应 |
| application/x-www-form-urlencoded | 表单数据 | 表单提交 |
| multipart/form-data | 多部分数据 | 文件上传 |
| image/jpeg | JPEG图片 | 图片资源 |
| image/png | PNG图片 | 图片资源 |
| application/pdf | PDF文档 | PDF文件 |
示例:
bash
响应HTML:
Content-Type: text/html; charset=utf-8
响应JSON:
Content-Type: application/json
响应图片:
Content-Type: image/png
5.2 Content-Length
用途:指定Body的字节长度。
bash
Content-Length: 1024
重要性:
- 接收方知道要读取多少字节
- 如果没有Content-Length,需要用其他方式判断Body结束(如Connection: close)
5.3 Host
用途:指定请求的主机名和端口。
bash
Host: www.example.com:8080
为什么需要Host:
- 一个IP地址可能部署多个网站(虚拟主机)
- 服务器根据Host字段判断访问哪个网站
示例:
bash
同一台服务器(IP: 192.168.1.100)部署了三个网站:
- www.site1.com
- www.site2.com
- www.site3.com
请求 GET / HTTP/1.1
Host: www.site1.com
→ 返回site1的首页
请求 GET / HTTP/1.1
Host: www.site2.com
→ 返回site2的首页
5.4 User-Agent
用途:标识客户端的软件环境(浏览器类型、操作系统等)。
示例:
bash
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36
拆解:
Windows NT 10.0:Windows 10操作系统Win64; x64:64位系统Chrome/91.0.4472.124:Chrome浏览器版本91
应用场景:
- 服务器根据User-Agent返回不同内容(PC版/移动版)
- 统计访客使用的浏览器和操作系统
5.5 User-Agent的历史故事
为什么User-Agent这么复杂?
早期浏览器市场竞争激烈,为了兼容性,后来的浏览器会在User-Agent中加入"Mozilla"、"KHTML"、"Gecko"等字符串,假装自己是其他浏览器,以便网站正常工作。
bash
1993年 Mosaic浏览器:
User-Agent: NCSA_Mosaic/2.0
1994年 Netscape Navigator(代号Mozilla):
User-Agent: Mozilla/1.0
1995年 IE浏览器(为了兼容,加入Mozilla):
User-Agent: Mozilla/2.0 (compatible; MSIE 3.0)
2003年 Safari浏览器(基于KHTML引擎):
User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/124 (KHTML, like Gecko) Safari/125
现在的Chrome:
User-Agent: Mozilla/5.0 ... AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91 Safari/537.36
所以现在所有浏览器的User-Agent都包含"Mozilla",非常魔幻。
5.6 Cookie
用途:客户端存储少量数据,每次请求自动发送给服务器。
工作流程:
bash
1. 客户端首次访问
GET / HTTP/1.1
2. 服务器设置Cookie
HTTP/1.1 200 OK
Set-Cookie: session_id=abc123; Path=/; HttpOnly
3. 客户端后续请求自动带上Cookie
GET /profile HTTP/1.1
Cookie: session_id=abc123
4. 服务器根据session_id识别用户
Cookie属性:
Path=/:Cookie的有效路径Domain=example.com:Cookie的有效域名Expires=...:过期时间HttpOnly:禁止JavaScript访问(防止XSS攻击)Secure:只在HTTPS下发送
5.7 Referer
用途:标识请求的来源页面。
bash
用户在www.google.com搜索,点击搜索结果跳转到www.example.com
GET / HTTP/1.1
Host: www.example.com
Referer: https://www.google.com/search?q=example
应用场景:
- 统计流量来源
- 防盗链(检查Referer,拒绝非法引用)
- 安全检查(防止CSRF攻击)
5.8 Accept系列
客户端告诉服务器自己能接受什么类型的内容。
bash
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Accept:能接受的内容类型Accept-Encoding:能接受的压缩算法Accept-Language:能接受的语言
q值表示优先级(0-1),默认1.0。
六、本篇总结
6.1 核心要点
HTTP方法:
- GET:获取资源,参数在URL,幂等
- POST:提交数据,参数在Body,非幂等
- HEAD:获取响应头,不返回Body
- PUT:更新资源,幂等
- DELETE:删除资源,幂等
- OPTIONS:查询支持的方法
HTML表单:
- GET表单:参数拼接到URL
- POST表单:参数在Body
- Content-Type:application/x-www-form-urlencoded、multipart/form-data、application/json
HTTP状态码:
- 1xx:信息性(100 Continue)
- 2xx:成功(200 OK、201 Created、204 No Content)
- 3xx:重定向(301、302、304)
- 4xx:客户端错误(400、401、403、404)
- 5xx:服务器错误(500、502、503、504)
重定向:
- 301永久重定向:网站换域名、搜索引擎更新索引
- 302临时重定向:登录跳转、搜索引擎保留原索引
- Location字段指定目标URL
常见Header:
- Content-Type:Body的媒体类型
- Content-Length:Body的字节长度
- Host:请求的主机名和端口
- User-Agent:客户端软件环境
- Cookie:客户端存储数据
- Referer:请求来源页面
6.2 容易混淆的点
-
GET和POST的本质区别:语义不同(获取vs提交),GET幂等、POST非幂等。"GET不安全、POST安全"是错的。
-
301和302的选择:永久改变用301,临时跳转用302。搜索引擎对待它们完全不同。
-
401和403的区别:401是未认证(未登录),403是无权限(登录了但权限不足)。
-
Content-Type和Accept:Content-Type是发送方声明数据类型,Accept是接收方声明能接受的类型。
-
Referer的拼写:HTTP协议中拼成了"Referer"(少了一个r),这是历史遗留的拼写错误,但已经无法修改。
-
User-Agent为什么都有Mozilla:历史原因,所有现代浏览器都在User-Agent中加入了"Mozilla"以实现兼容性。
💬 总结:这一篇详细讲解了HTTP方法(GET、POST等)、状态码(200、404、301等)、常见Header(Content-Type、User-Agent、Cookie等),包括它们的含义、使用场景、实际应用。理解了这些,就能处理各种HTTP应用场景,包括表单提交、文件上传、重定向、缓存控制等。下一篇会实现完整的HTTP服务器,支持静态资源、动态请求、GET/POST参数解析,把所有知识点串起来。
👍 点赞、收藏与分享:如果这篇帮你理解了HTTP方法、状态码和Header,请点赞收藏!下一篇会把完整的HTTP服务器实现出来!