HTTP(Hypertext Transfer Protocol,超文本传输协议)是浏览器、客户端、服务器和 Web 服务之间通信的基础协议。无论是访问网页、提交表单、调用 API,还是下载文件,都离不开 HTTP。
一次典型的 HTTP 通信包含请求和响应两个部分:
- HTTP 请求(Request):客户端向服务器发送请求方法、请求目标、请求头以及可选的请求体。
- HTTP 响应(Response):服务器返回状态码、响应头以及可选的响应体。
例如,浏览器访问一个网页时,可能发送 GET 请求,服务器最终返回 200 OK;如果请求的资源不存在,则可能返回 404 Not Found。
需要注意的是,HTTP 状态码只是排查问题的一个线索。要完整理解一次 HTTP 通信,还需要了解请求方法、请求头、请求体、响应头、响应体、缓存机制、重定向以及服务器日志。
一、HTTP 请求与响应的基本结构
1. HTTP 请求
HTTP/1.1 的典型请求如下:
GET /article.php?id=123 HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0
Accept: text/html
Accept-Language: zh-CN,zh;q=0.9
Connection: keep-alive
上面的请求由多个部分组成。
- GET:请求方法,表示客户端希望获取资源。
- /article.php?id=123:请求目标,包含资源路径和查询参数。
- HTTP/1.1:使用的 HTTP 协议版本。
- Host:指定请求目标的主机名。
- User-Agent:描述客户端软件的信息。
- Accept:声明客户端能够接受的响应媒体类型。
- Accept-Language:声明客户端偏好的自然语言。
- Connection:用于管理 HTTP/1.x 连接的字段。
需要注意,HTTP/2 和 HTTP/3 使用不同的消息传输格式,不能将上述 HTTP/1.1 文本形式直接等同于它们在线路上的实际表示。
2. HTTP 响应
服务器可能返回以下响应:
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 22
Cache-Control: no-cache
<h1>Hello, HTTP!</h1>
这份响应包含以下内容:
- 200:HTTP 状态码,表示请求成功。
- OK:原因短语,不决定状态码的协议含义。
- Content-Type:声明响应内容的媒体类型。
- Content-Length:表示消息内容长度。
- Cache-Control:控制缓存行为。
- 空行:用于分隔响应头和响应体。
- 响应体:服务器实际返回的内容,这里是 HTML。
实际开发中,状态码用于判断请求的大致处理结果,而响应头和响应体则能够提供更多信息。
二、HTTP 请求方法大全
HTTP 请求方法用于表达客户端希望服务器对目标资源执行什么操作。服务器收到请求后,会结合资源状态、访问权限、请求内容和业务逻辑进行处理。
以下按照 IANA HTTP Method Registry 中登记的方法进行整理。并非所有服务器或 URL 都支持每一种方法。
1. 常见请求方法
- GET:获取资源。常用于获取网页、图片、文章和接口数据。
- HEAD:获取响应头,不返回响应内容,常用于检查资源状态。
- POST:提交数据,常用于提交表单、创建资源或执行业务操作。
- PUT:创建资源或替换目标资源的当前表示。
- DELETE:请求删除指定资源。
- CONNECT:建立隧道,常用于通过代理建立 HTTPS 隧道。
- OPTIONS:查询通信选项,也常用于浏览器跨域请求的预检。
- TRACE:用于消息回环测试,实际部署中通常需要谨慎处理。
- PATCH:对资源进行部分修改。
2. WebDAV 与其他扩展请求方法
部分请求方法来自 WebDAV、DeltaV 等扩展协议,通常用于远程文件管理、资源绑定和版本控制等场景。
- ACL:访问控制列表操作。
- BASELINE-CONTROL:基线控制,属于 DeltaV 版本控制扩展。
- BIND:绑定资源,属于 WebDAV 扩展。
- CHECKIN:检入版本,属于 DeltaV 扩展。
- CHECKOUT:检出版本,属于 DeltaV 扩展。
- COPY:复制资源,属于 WebDAV。
- LABEL:版本标签操作,属于 DeltaV。
- LINK:建立链接关系,属于已注册的扩展方法。
- LOCK:锁定资源,属于 WebDAV。
- MERGE:合并版本,属于 DeltaV。
- MKACTIVITY:创建活动资源,属于 DeltaV。
- MKCALENDAR:创建日历集合,属于日历扩展。
- MKCOL:创建集合,属于 WebDAV。
- MKREDIRECTREF:创建重定向引用,属于 WebDAV 扩展。
- MKWORKSPACE:创建工作区,属于 DeltaV。
- MOVE:移动资源,属于 WebDAV。
- ORDERPATCH:修改集合顺序,属于 WebDAV 扩展。
- PRI:与 HTTP/2 连接前言相关的特殊方法标记。
- PROPFIND:查询资源属性,属于 WebDAV。
- PROPPATCH:修改资源属性,属于 WebDAV。
- REBIND:重新绑定资源,属于 WebDAV 绑定扩展。
- REPORT:查询报告,常用于 WebDAV、DeltaV 等扩展。
- SEARCH:搜索资源,属于已注册的扩展方法。
- UNBIND:解除绑定,属于 WebDAV 绑定扩展。
- UNCHECKOUT:取消检出,属于 DeltaV。
- UNLINK:解除链接关系,属于已注册的扩展方法。
- UNLOCK:解除资源锁定,属于 WebDAV。
- UPDATE:更新版本,属于 DeltaV。
- UPDATEREDIRECTREF:更新重定向引用,属于 WebDAV 扩展。
- VERSION-CONTROL:版本控制操作。
官方注册表可能继续增加新方法,因此完整清单应以 IANA 当前登记内容为准。
3. 常见请求方法之间的区别
GET 与 POST
GET 通常用于读取资源,而 POST 通常用于提交数据或执行资源相关处理。
GET 请求的预期语义应当是安全的,也就是不应通过 GET 请求执行删除账户、扣款等具有业务修改效果的操作。
POST 则可以用于创建资源、提交表单、执行搜索或触发其他业务逻辑,具体行为由服务器定义。
PUT 与 PATCH
PUT 用于创建或替换目标资源的当前表示,而 PATCH 用于修改资源的部分内容。
例如,完整更新用户资料可以使用 PUT,而只修改用户昵称时可以考虑使用 PATCH。具体选择还需要符合接口设计规范。
DELETE
DELETE 用于请求删除指定资源。请求成功时,服务器可以根据处理情况返回 200 OK、202 Accepted 或 204 No Content 等状态码。
幂等性并不意味着重复请求每次都会得到相同的响应,而是指重复执行相同请求时,其预期效果与执行一次相同。
HEAD
HEAD 与 GET 类似,但服务器不返回响应内容。它可以用于检查资源是否存在、获取响应头或辅助判断缓存情况。
OPTIONS
OPTIONS 用于查询目标资源支持的通信选项。在浏览器跨域请求中,OPTIONS 还经常被用于 CORS 预检。
4. 安全方法与幂等方法
理解安全方法和幂等方法,有助于正确设计接口、缓存策略和重试机制。
安全方法
安全方法表示请求的预期语义是只读的,不应要求服务器执行资源修改操作。
常见安全方法包括:
- GET
- HEAD
- OPTIONS
- TRACE
幂等方法
幂等表示重复执行相同请求,其预期效果与执行一次相同。它不代表每次响应都完全相同,也不代表不会产生日志等额外副作用。
常见幂等方法包括:
- GET
- HEAD
- OPTIONS
- TRACE
- PUT
- DELETE
POST 通常不具有幂等性。PATCH 是否幂等,则取决于具体的操作语义和接口实现。
CONNECT 通常既不属于安全方法,也不属于幂等方法。
三、HTTP 请求头:服务器收到请求时会看到什么?
HTTP 请求头用于传递客户端信息、认证凭据、内容类型、缓存条件、代理信息以及其他请求参数。
HTTP 规范登记了大量字段,下面按照用途介绍常见请求头。
1. 请求目标、客户端与来源信息
Host
指定请求目标的主机名,在 HTTP/1.1 中通常是必需的。
User-Agent
描述发起请求的客户端软件信息,可能包含浏览器名称、版本和操作系统等内容。
Referer
提供来源页面的地址,但实际发送内容可能受到浏览器隐私策略和 Referrer-Policy 的限制。
From
提供用户代理背后用户的联系信息,实际使用较少。
Origin
表示发起请求的来源,通常包含协议、主机和端口信息,常用于跨域资源共享(CORS)判断。
Forwarded
用于在代理链中传递客户端地址、协议等信息。
Via
记录请求经过的代理或网关。
Max-Forwards
限制 TRACE 或 OPTIONS 请求经过的代理跳数。
需要注意,Host、Origin、Referer 等字段不能单独证明请求来自可信用户。攻击者可以自行构造 HTTP 请求并填写这些字段,因此服务器不能将它们当作身份认证的替代品。
2. 内容类型与内容协商
Accept
声明客户端可以接受的响应媒体类型,例如 text/html 或 application/json。
Accept-Charset
用于表达字符集偏好,现代 HTTP 使用场景中已经不常用。
Accept-Encoding
声明客户端能够接受的内容编码,例如 gzip、br。
Accept-Language
声明客户端偏好的自然语言,例如 zh-CN 或 en-US。
Content-Type
声明请求体的媒体类型,例如:
application/jsonapplication/x-www-form-urlencodedmultipart/form-datatext/plain
Content-Encoding
声明请求体采用的内容编码。
Content-Language
声明请求内容使用的语言。
Content-Length
表示消息内容长度,具体规则取决于协议版本和消息格式。
Content-Location
提供与请求内容相关的资源标识。
Expect
声明客户端对服务器行为的预期,常见值为 100-continue。
TE
在 HTTP/1.1 中声明客户端可以接受的传输编码或 trailers。
Trailer
声明消息末尾可能出现的尾部字段。
Transfer-Encoding
用于 HTTP/1.1 消息的传输编码,例如 chunked。
这几个字段的区别尤其重要:
- Content-Type:描述内容是什么。
- Content-Encoding:描述内容采用了什么编码。
- Transfer-Encoding:涉及 HTTP/1.1 消息的传输编码。
三者不能混为一谈。
3. 身份认证与授权
Authorization
向服务器提交认证凭据,常见形式包括 Basic 和 Bearer。
Cookie
向服务器发送与当前请求匹配的 Cookie。
Proxy-Authorization
向代理服务器提供认证凭据。
Signature
在相应的 HTTP 消息签名机制中传递签名信息。
Signature-Input
声明 HTTP 消息签名的输入参数。
常见的身份认证方式包括 Basic 认证、Bearer 令牌等。
认证信息应通过 HTTPS 传输。服务器还需要验证凭据是否有效、令牌是否过期,以及当前用户是否具有执行操作的权限。
需要注意,身份认证与授权是两个不同的环节:认证用于确认访问者的身份,授权用于判断该身份是否可以执行相应操作。
4. 缓存与条件请求
Cache-Control
控制缓存行为,可以用于指定资源是否允许缓存以及缓存的有效期等。
Pragma
属于较早期的缓存控制字段,常用于兼容性场景,例如 no-cache。
If-Match
只有在资源的实体标签匹配时,才继续执行相应请求。
If-None-Match
根据实体标签判断资源是否符合条件,常用于缓存验证。
If-Modified-Since
用于判断资源在指定时间后是否发生修改。
If-Unmodified-Since
只有在资源未于指定时间后发生修改时,才满足相应前置条件。
If-Range
当指定条件满足时返回请求的资源范围,否则返回完整内容。
Range
请求资源的某一段内容,常用于断点续传和分段下载。
例如,客户端请求一个 CSS 文件:
GET /style.css HTTP/1.1
Host: www.example.com
If-None-Match: "abc123"
如果资源仍符合缓存验证条件,服务器可能返回 304 Not Modified,让客户端继续使用已有缓存,而不必重新下载完整内容。
5. 连接、代理与协议升级
Connection
用于管理 HTTP/1.x 的逐跳连接选项。
Upgrade
请求切换协议。
Keep-Alive
用于旧式 HTTP 连接保持参数。
Proxy-Connection
非标准的历史代理字段,不应将其当作通用 HTTP 标准字段。
Alt-Used
指示客户端使用的替代服务端点。
Early-Data
与早期数据请求处理有关。
Priority
用于表达请求处理优先级信息。
TE
在 HTTP/1.1 中表达传输编码相关偏好。
需要特别注意,HTTP/2 和 HTTP/3 不允许像 HTTP/1.1 那样使用 Connection 等逐跳字段控制连接。因此,排查相关问题时,需要先确认实际使用的协议版本。
6. 跨域请求(CORS)
跨域资源共享机制允许服务器通过特定响应头声明哪些跨域请求可以被浏览器允许。
常见的 CORS 请求头包括:
Origin
表示发起请求的来源。
Access-Control-Request-Method
在预检请求中声明后续实际请求准备使用的方法。
Access-Control-Request-Headers
在预检请求中声明后续实际请求准备使用的请求头。
以下字段通常由服务器在响应中返回:
- Access-Control-Allow-Origin:声明允许的跨域来源。
- Access-Control-Allow-Methods:声明允许的跨域请求方法。
- Access-Control-Allow-Headers:声明允许的跨域请求头。
- Access-Control-Allow-Credentials:声明跨域请求是否允许携带凭据。
- Access-Control-Expose-Headers:声明浏览器脚本可以读取的额外响应头。
- Access-Control-Max-Age:指定 CORS 预检结果的缓存时间。
CORS 主要由浏览器执行相关访问控制规则。它不是服务器身份认证机制,也不能代替服务器端的权限校验。
7. 浏览器安全与客户端提示
Sec-Fetch-Site
描述请求与发起页面之间的站点关系。
Sec-Fetch-Mode
描述请求模式。
Sec-Fetch-Dest
描述请求目标类型。
Sec-Fetch-User
表示请求是否由用户激活触发,适用范围有限。
Sec-CH-UA
提供用户代理品牌相关的客户端提示。
Sec-CH-UA-Mobile
提供设备移动属性提示。
Sec-CH-UA-Platform
提供平台信息提示。
DNT
旧式的“不跟踪”偏好字段。
Save-Data
用于表达节省数据的偏好,属于扩展用途。
这些字段可以辅助浏览器兼容性、安全策略和内容适配,但不能替代身份认证和服务端授权。
8. 服务器收到请求后会检查什么?
服务器收到 HTTP 请求后,通常需要检查以下内容:
- 请求方法:确认请求方法是否被识别,以及目标资源是否允许该方法。
- 请求目标和协议格式:检查 URL、协议格式以及必要字段是否正确。
- 身份认证与访问权限:确认用户是否已经完成认证,以及是否有权访问目标资源。
- 请求头和请求体:检查内容类型、参数格式、JSON 结构和上传文件等是否符合接口要求。
- 请求大小和访问频率:检查上传限制、请求体大小以及限流规则。
- 业务数据:检查参数是否有效、目标资源是否存在,以及业务条件是否满足。
- 缓存和跨域策略:确认条件请求、范围请求和 CORS 规则是否正确。
- 后端服务状态:检查数据库、文件系统以及上游服务是否能够正常完成操作。
根据失败原因,服务器可能返回 400、401、403、404、405、413、415、422、429 或 5xx 等状态码。
四、HTTP 响应头:服务器返回给客户端什么?
HTTP 响应头用于描述响应内容、缓存策略、资源位置、认证要求、安全策略以及其他响应信息。
下面介绍常见响应头及其用途。
1. 内容与资源信息
Date
表示响应生成时间。
Server
提供服务器软件信息,出于安全考虑,服务器可以选择限制暴露的细节。
Content-Type
声明响应内容的媒体类型,例如 HTML、JSON 或图片。
Content-Length
表示响应内容长度。
Content-Encoding
声明响应内容采用的编码。
Content-Language
声明响应内容使用的语言。
Content-Location
提供响应内容对应的资源位置。
Accept-Ranges
声明服务器是否支持资源范围请求。
Content-Range
描述部分内容在完整资源中的范围。
2. 缓存与资源验证
Cache-Control
控制缓存策略,例如缓存有效期和缓存使用条件。
Expires
提供资源过期时间。
ETag
为资源表示提供实体标签,常用于缓存验证和条件请求。
Last-Modified
表示资源最后修改时间。
Vary
声明哪些请求字段会影响响应内容,从而帮助缓存系统区分不同的响应版本。
Age
表示缓存响应的大致存储时间。
Warning
属于旧式缓存警告字段,已从现代 HTTP 规范中移除。
在网站性能优化中,Cache-Control、ETag、Last-Modified 和 Vary 尤其重要。合理配置这些字段,有助于减少重复下载、降低服务器负载并改善页面加载体验。
3. 重定向、认证与请求控制
Location
指示重定向目标,或者在创建资源等场景中提供新资源的位置。
Retry-After
建议客户端在何时重试请求。
Allow
声明目标资源允许使用的请求方法。
WWW-Authenticate
提供服务器认证挑战信息。
Proxy-Authenticate
提供代理认证挑战信息。
Authentication-Info
提供认证过程相关信息。
Proxy-Authentication-Info
提供代理认证过程相关信息。
Set-Cookie
设置或更新 Cookie,常用于维护登录状态和会话信息。
4. 跨域响应头
Access-Control-Allow-Origin
声明允许访问资源的跨域来源。
Access-Control-Allow-Methods
声明允许的跨域请求方法。
Access-Control-Allow-Headers
声明允许的跨域请求头。
Access-Control-Allow-Credentials
声明跨域请求是否允许携带凭据。
Access-Control-Expose-Headers
声明跨域响应中可以由浏览器脚本读取的响应头。
Access-Control-Max-Age
指定 CORS 预检结果的缓存时间。
配置跨域策略时,应根据实际业务需要设置允许的来源、方法和请求头,不要在需要凭据的场景中随意使用不符合规范的配置。
5. 安全相关响应头
Strict-Transport-Security
声明浏览器应使用 HTTPS 访问网站。
Content-Security-Policy
配置内容安全策略,用于限制页面能够加载和执行的资源。
Content-Security-Policy-Report-Only
以报告模式测试内容安全策略,而不直接执行相应的阻止策略。
X-Content-Type-Options
常用于设置 nosniff,限制浏览器对资源 MIME 类型的嗅探。
X-Frame-Options
控制页面能否被嵌入框架,常用于降低点击劫持风险。
Referrer-Policy
控制来源信息的发送策略。
Permissions-Policy
控制部分浏览器功能的使用权限。
Cross-Origin-Resource-Policy
控制其他来源对资源的跨源加载。
Cross-Origin-Opener-Policy
控制跨源窗口上下文之间的关系。
Cross-Origin-Embedder-Policy
控制文档加载跨源资源的策略。
这些响应头可以帮助网站建立更完善的浏览器安全策略,但不能单独保证网站完全安全。仍然需要结合 HTTPS、身份认证、权限控制、输入验证和安全编码等措施。
6. 代理、替代服务与性能信息
Alt-Svc
声明访问服务的替代端点。
Via
记录响应经过的代理或网关。
Server-Timing
向客户端暴露服务器端性能计时信息,可辅助排查数据库查询、接口处理和其他服务器耗时。
NEL
用于配置网络错误日志相关机制。
Reporting-Endpoints
声明接收报告的端点。
在反向代理环境中,还经常会看到 X-Forwarded-For 和 X-Real-IP 等字段。这些字段通常用于传递客户端 IP 信息,但其可信度取决于代理配置。
应用程序不能无条件相信客户端自行提交的 IP 字段。应当仅信任由自己控制或明确配置的可信代理所提供的相关信息。
五、HTTP 状态码完整列表
HTTP 状态码是服务器对请求处理结果的分类标识,通常由三位数字组成。标准状态码范围为 100–599。
根据状态码的首位数字,可以将其划分为五类。
- 1xx 信息响应:表示请求已被接收,处理仍在继续,或者客户端可以继续后续操作。
- 2xx 成功响应:表示请求已被成功接收、理解或处理。
- 3xx 重定向:表示客户端需要采取进一步操作,才能完成请求。
- 4xx 客户端错误:表示请求存在问题,或者服务器拒绝执行该请求。
- 5xx 服务器错误:表示服务器在处理有效请求时遇到了问题,或者无法完成请求。
以下依据 IANA HTTP Status Code Registry 整理已登记的状态码,并对未分配的数字进行说明。
1. 1xx 信息响应
100 Continue
请求的初始部分已经接收,客户端可以继续发送请求内容。
101 Switching Protocols
服务器正在根据客户端请求切换协议。
102 Processing
请求正在处理,属于 WebDAV 扩展状态码。
103 Early Hints
服务器提前向客户端提供提示信息,例如可以提前加载的资源。
104 Upload Resumption Supported
表示支持上传恢复,属于临时注册状态码,其登记信息可能随官方更新而变化。
未分配状态码:
- 105–199:未分配。
需要注意,1xx 响应通常属于信息性响应,而不是最终的请求处理结果。
2. 2xx 成功响应
200 OK
请求成功。服务器通常会根据请求类型返回相应的资源或处理结果。
201 Created
请求成功创建了资源。服务器可以通过 Location 响应头提供新资源的位置。
202 Accepted
请求已被接受,但处理尚未完成。它不代表相关操作一定会最终成功。
203 Non-Authoritative Information
服务器返回的信息不是原始服务器的权威信息。
204 No Content
请求成功,但没有需要返回的响应内容。
205 Reset Content
请求成功,客户端应重置当前视图。
206 Partial Content
服务器成功返回了资源的一部分,常用于 Range 范围请求和断点续传。
207 Multi-Status
返回多个资源的状态信息,属于 WebDAV 扩展。
208 Already Reported
表示资源已经在多状态响应中报告,属于 WebDAV 扩展。
226 IM Used
服务器返回经过实例操作处理的结果。
未分配状态码:
- 209–225:未分配。
- 227–299:未分配。
在日常开发中,最常见的成功状态码是 200 OK、201 Created 和 204 No Content。
3. 3xx 重定向
300 Multiple Choices
请求的资源存在多个可选表示。
301 Moved Permanently
资源已经永久移动到新的地址,通常用于网站 URL 永久迁移。
302 Found
资源暂时位于另一个地址,属于临时重定向。
303 See Other
客户端应通过另一个地址获取结果,通常使用 GET 请求访问目标资源。
304 Not Modified
资源未发生需要重新获取的变化,客户端可以继续使用已有缓存。
305 Use Proxy
历史上用于指示客户端使用代理,已经不推荐使用。
306 Unused
已登记但未使用的状态码。
307 Temporary Redirect
临时重定向,并要求用户代理保留原请求方法。
308 Permanent Redirect
永久重定向,并要求用户代理保留原请求方法。
未分配状态码:
- 309–399:未分配。
301、302、307 和 308 的区别
301 Moved Permanently
表示永久重定向。对于某些历史兼容行为,用户代理可能将 POST 请求转换为 GET 请求。
302 Found
表示临时重定向。对于某些历史兼容行为,用户代理也可能将 POST 请求转换为 GET 请求。
307 Temporary Redirect
表示临时重定向,并要求保留原请求方法和请求内容。
308 Permanent Redirect
表示永久重定向,并要求保留原请求方法和请求内容。
在网站 SEO 中,301 和 308 通常用于永久迁移 URL;302 和 307 通常用于临时跳转。实际选择时,应根据资源迁移的性质和请求方法处理需求决定。
4. 4xx 客户端错误
400 Bad Request
请求格式错误,或者请求内容不符合服务器要求。
常见原因包括参数格式不正确、JSON 语法错误以及请求结构不合法。
401 Unauthorized
请求缺少有效的身份认证凭据。
常见原因包括用户未登录、令牌无效或者认证信息已经过期。
402 Payment Required
为支付相关用途预留的状态码。
403 Forbidden
服务器拒绝执行请求。
即使用户已经登录,也可能因为权限不足、安全规则或访问控制策略而收到该状态码。
404 Not Found
请求的资源未找到。
常见原因包括 URL 错误、资源已被删除、路由配置不正确或目标文件不存在。
405 Method Not Allowed
请求方法不被目标资源允许。
服务器可以通过 Allow 响应头声明目标资源支持的方法。
406 Not Acceptable
服务器无法提供满足客户端内容协商要求的响应表示。
407 Proxy Authentication Required
客户端需要先通过代理服务器的身份认证。
408 Request Timeout
服务器未能在规定时间内接收到完整请求。
409 Conflict
请求与资源当前状态发生冲突。
例如,修改数据时发生版本冲突。
410 Gone
请求的资源已经永久消失,服务器明确表示该资源不再可用。
411 Length Required
服务器要求请求提供必要的内容长度信息。
412 Precondition Failed
请求中的前置条件不成立。
413 Content Too Large
请求内容过大,超过服务器允许的限制。
常见于文件上传大小超出限制的场景。
414 URI Too Long
请求 URI 过长,服务器无法处理。
415 Unsupported Media Type
服务器不支持请求内容所使用的媒体类型或编码形式。
例如,接口要求 JSON,但客户端提交了不符合要求的内容类型。
416 Range Not Satisfiable
服务器无法满足客户端请求的资源范围。
417 Expectation Failed
服务器无法满足请求中的 Expect 条件。
418 I'm a teapot
源于特殊用途协议定义,实际支持情况取决于具体实现。
421 Misdirected Request
请求被发送到无法处理该请求的服务器。
422 Unprocessable Content
请求格式正确,但服务器无法处理其中的内容。
例如,请求结构符合要求,但字段未通过业务验证。
423 Locked
资源已经被锁定,属于 WebDAV 扩展。
424 Failed Dependency
由于依赖操作失败,当前操作无法完成,属于 WebDAV 扩展。
425 Too Early
服务器不愿处理可能被重放的早期请求。
426 Upgrade Required
客户端需要升级协议才能继续请求。
428 Precondition Required
服务器要求请求必须包含前置条件。
429 Too Many Requests
客户端在指定时间内发送了过多请求,服务器正在执行限流。
服务器可以通过 Retry-After 响应头建议客户端何时重试。
431 Request Header Fields Too Large
请求头字段过大,服务器拒绝处理请求。
451 Unavailable For Legal Reasons
服务器因法律原因无法提供相应资源。
未分配状态码:
- 419–420:未分配。
- 427:未分配。
- 430:未分配。
- 432–450:未分配。
- 452–499:未分配。
5. 5xx 服务器错误
500 Internal Server Error
服务器内部发生错误,无法完成请求。
常见原因包括程序异常、数据库错误、未处理的异常以及代码逻辑问题。
501 Not Implemented
服务器不支持完成请求所需的功能。
502 Bad Gateway
作为网关或代理的服务器从上游服务器收到了无效响应。
例如,反向代理无法正确获取 PHP-FPM 或其他后端服务的响应。
503 Service Unavailable
服务器暂时无法处理请求。
常见原因包括服务维护、服务器负载过高或后端服务暂时不可用。
504 Gateway Timeout
网关或代理在等待上游服务器响应时发生超时。
505 HTTP Version Not Supported
服务器不支持请求使用的 HTTP 版本。
506 Variant Also Negotiates
服务器的内容协商配置存在问题。
507 Insufficient Storage
服务器没有足够的存储空间完成请求,属于 WebDAV 扩展。
508 Loop Detected
服务器在处理请求时检测到循环,属于 WebDAV 扩展。
510 Not Extended
与历史上的扩展请求机制有关,已废弃。
511 Network Authentication Required
客户端需要先完成网络认证才能访问网络资源。
未分配状态码:
- 509:未分配。
- 512–599:未分配。
需要注意,服务器错误不一定意味着服务器主机本身发生故障。问题也可能来自反向代理、PHP-FPM、数据库连接或其他上游服务。
6. 常见的非标准状态码
除了 IANA 通用 HTTP 状态码注册表中的状态码之外,一些服务器、代理和 CDN 还会使用自己的错误数字。
这些数字可能在特定产品中有明确含义,但不能直接当作通用 HTTP 标准状态码使用。
499 Client Closed Request
常见于 Nginx 的特定日志或实现,通常表示客户端在服务器完成响应之前关闭了请求。
520 Web Server Returned an Unknown Error
Cloudflare 特定错误码,表示边缘网络无法从源站获得可识别的正常响应。
521 Web Server Is Down
Cloudflare 特定错误码,通常表示源站拒绝连接或无法正常接受连接。
522 Connection Timed Out
Cloudflare 特定错误码,表示与源站建立连接时发生超时。
523 Origin Is Unreachable
Cloudflare 特定错误码,表示源站无法访问。
524 A Timeout Occurred
Cloudflare 特定错误码,通常表示已经成功建立连接,但源站未能在规定时间内返回响应。
525 SSL Handshake Failed
Cloudflare 特定错误码,表示与源站建立 SSL/TLS 握手时失败。
526 Invalid SSL Certificate
Cloudflare 特定错误码,通常与源站 SSL 证书验证失败有关。
527 Railgun Error
与特定 Cloudflare 功能有关,具体适用性应以官方文档为准。
排查这些错误时,应结合 CDN 控制台、源站访问日志、Nginx 错误日志、TLS 证书配置和服务器连接状态进行判断。
六、HTTP 状态码与请求头的配合示例
理解状态码的最好方式之一,就是结合实际请求和响应进行分析。
1. 200 OK:请求成功
客户端请求:
GET /api/users HTTP/1.1
Host: www.example.com
Accept: application/json
服务器响应:
HTTP/1.1 200 OK
Content-Type: application/json
{"users":[]}
这表示请求成功,服务器返回了 JSON 格式的数据。
需要注意,HTTP 状态码为 200 并不意味着业务操作一定达到了用户预期。客户端仍然需要根据响应体判断实际业务结果。
2. 201 Created:创建资源成功
客户端提交:
POST /api/articles HTTP/1.1
Host: www.example.com
Content-Type: application/json
{"title":"HTTP 状态码详解"}
服务器响应:
HTTP/1.1 201 Created
Location: /api/articles/123
Content-Type: application/json
{"id":123,"title":"HTTP 状态码详解"}
服务器成功创建了资源。
其中,Location 响应头可以指示新建资源的位置,响应体则返回了新资源的相关信息。
3. 304 Not Modified:缓存验证
客户端发送:
GET /style.css HTTP/1.1
Host: www.example.com
If-None-Match: "abc123"
如果资源符合缓存验证条件,服务器可以返回:
HTTP/1.1 304 Not Modified
ETag: "abc123"
这表示客户端可以继续使用已有缓存,而不必重新下载完整的 CSS 文件。
304 响应通常不包含需要重新下载的资源正文,因此有助于减少重复传输。
4. 401 Unauthorized:认证问题
服务器可能返回:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer
这表示客户端需要提供符合相应认证机制的凭据。
实际处理时,应进一步检查登录状态、访问令牌、令牌有效期和认证配置。
5. 405 Method Not Allowed:请求方法不被允许
服务器可能返回:
HTTP/1.1 405 Method Not Allowed
Allow: GET, HEAD
这表示当前资源不允许使用客户端提交的请求方法。
Allow 响应头说明目标资源允许使用哪些请求方法。
排查时,应检查接口路由、服务器配置和客户端实际使用的请求方法。
6. 429 Too Many Requests:请求过于频繁
服务器可能返回:
HTTP/1.1 429 Too Many Requests
Retry-After: 60
这表示客户端发送请求的频率超过了服务器允许的限制。
Retry-After 在这个示例中用于建议客户端等待 60 秒后再重试。
对于接口调用、爬虫访问和登录请求,应合理设置访问频率,并根据业务场景配置限流策略。
七、HTTP 请求与响应问题排查
遇到 HTTP 错误时,不要只看状态码就直接下结论。建议按照以下顺序进行排查。
1. 检查请求方法和 URL
确认请求地址是否正确,路径、查询参数以及请求方法是否符合接口要求。
如果访问的是文章页面,还应检查文章 ID、分类参数以及对应的路由配置。
2. 检查请求头
重点检查以下字段:
- Content-Type
- Accept
- Authorization
- Cookie
- Cache-Control
- If-None-Match
- If-Modified-Since
- 与代理有关的字段
请求头不符合接口要求时,服务器可能返回 400、401、403、406 或 415 等状态码。
3. 检查请求体
对于 POST、PUT 和 PATCH 等请求,应确认请求体的格式和内容是否符合接口要求。
如果提交 JSON,应检查 JSON 语法;如果提交表单,应检查字段名称和字段值;如果上传文件,应检查文件大小、类型以及服务器上传限制。
4. 检查状态码与响应体
状态码能够帮助确定错误的大致类别,但具体原因往往需要结合响应体判断。
例如,400 可能来自参数格式错误,422 可能来自业务校验失败,而 500 则可能来自服务器程序异常。
不要只根据一个状态码就认定故障来源。
5. 检查浏览器开发者工具
在浏览器中按 F12 打开开发者工具,进入 Network(网络)面板。
重点查看:
- 请求 URL 和请求方法。
- 请求头和响应头。
- 请求载荷或表单数据。
- 响应内容。
- HTTP 状态码。
- 请求耗时。
- 是否发生重定向。
- 是否命中浏览器缓存。
- 是否出现 CORS 或连接错误。
通过这些信息,通常能够初步判断问题发生在客户端、网络链路还是服务端。
6. 检查服务器日志
对于使用 Nginx、PHP-FPM 和数据库的网站,可以重点检查:
- Nginx 访问日志。
- Nginx 错误日志。
- PHP-FPM 日志。
- PHP 应用程序日志。
- 数据库错误日志。
如果浏览器只显示 500,而服务器日志中记录了 PHP 异常或数据库连接失败,就可以进一步定位到具体的代码或服务。
7. 检查反向代理与 CDN
如果网站使用 Cloudflare 等 CDN,或者使用 Nginx 作为反向代理,需要判断错误究竟来自客户端、CDN 边缘节点、反向代理还是源站应用。
例如:
- 源站正常,但 CDN 无法连接源站,可能出现 CDN 特定错误。
- Nginx 无法连接 PHP-FPM,可能返回 502。
- PHP-FPM 已经接收请求,但执行时间过长,可能导致代理超时。
- 源站本身返回 500,则需要进一步检查 PHP 程序或数据库。
这些情况可能表现为相似的页面错误,但根本原因并不相同。
8. 检查数据库和上游服务
对于 5xx 错误,应进一步检查数据库连接、查询耗时、文件系统权限、服务进程状态、网络连接和超时配置。
尤其是在高并发或复杂业务场景中,数据库连接池耗尽、慢查询和后端服务响应缓慢,都可能引发请求失败。
9. 常见状态码的排查方向
400 Bad Request
优先检查请求参数、请求格式、JSON 语法和必要字段。
401 Unauthorized
优先检查登录状态、访问令牌、认证凭据及其有效期。
403 Forbidden
优先检查用户权限、防火墙、WAF、安全规则和访问控制策略。
404 Not Found
优先检查 URL、路由、文件路径以及目标资源是否存在。
405 Method Not Allowed
优先检查请求方法和接口配置。
408 Request Timeout
优先检查网络连接、请求发送速度和超时配置。
413 Content Too Large
优先检查上传大小限制、请求体限制和相关代理配置。
415 Unsupported Media Type
优先检查请求媒体类型和接口要求是否一致。
422 Unprocessable Content
优先检查参数校验、字段格式和业务规则。
429 Too Many Requests
优先检查限流策略、访问频率以及是否存在异常请求。
500 Internal Server Error
优先检查应用异常、数据库错误、程序逻辑和 PHP 错误日志。
502 Bad Gateway
优先检查上游服务、PHP-FPM、反向代理连接和后端服务状态。
503 Service Unavailable
优先检查服务进程、服务器负载、维护状态和资源使用情况。
504 Gateway Timeout
优先检查上游响应时间、代理超时配置和数据库慢查询。
对于使用 Nginx、PHP-FPM、数据库和 CDN 的网站,尤其需要区分源站返回的状态码与 CDN 或代理自行生成的错误响应。两者看起来可能相似,但实际故障位置可能完全不同。
八、HTTP 状态码与 SEO
HTTP 状态码会影响搜索引擎对网页的抓取、重定向处理和资源状态判断。
对于网站运营者来说,正确配置状态码是技术 SEO 的重要组成部分。
1. 常见 SEO 场景
正常可访问的页面
正常页面通常应返回 200 OK,让搜索引擎能够正常获取页面内容。
永久更换 URL
当页面地址永久迁移时,通常可以使用 301 Moved Permanently 或 308 Permanent Redirect。
应确保重定向目标正确,并尽量避免不必要的多级跳转。
临时更换 URL
如果只是临时跳转,可以根据实际情况使用 302 Found 或 307 Temporary Redirect。
资源没有变化
在满足缓存验证条件时,服务器可以返回 304 Not Modified,减少重复传输。
页面确实不存在
对于不存在的页面,可以返回 404 Not Found;如果资源已经永久删除且明确不再提供,可以考虑返回 410 Gone。
服务器暂时故障
服务器出现临时故障时,应返回适当的 5xx 状态码,并尽快恢复服务。
不存在的页面却返回 200
如果不存在的页面显示错误信息,却仍然返回 200,可能导致搜索引擎将其识别为软 404。
2. SEO 优化注意事项
- 正常页面应返回正确的成功状态码,不要让错误页面伪装成正常页面。
- 永久迁移 URL 时,应使用合适的永久重定向,并确保目标地址正确。
- 不要将所有失效 URL 无差别地重定向到首页。
- 定期检查 404 页面、失效链接、重定向链和循环跳转。
- 如果网站持续返回 5xx,应尽快排查服务器负载、应用程序错误和上游服务故障。
- 对于可缓存资源,应合理使用 Cache-Control、ETag 和 Last-Modified 等字段。
- 确保站内链接、规范链接和站点地图中的 URL 与实际可访问地址一致。
需要注意,HTTP 状态码只是搜索引擎判断页面情况的信号之一,不能单独保证页面一定被收录或获得更高排名。页面内容质量、内部链接、抓取可访问性以及其他技术因素同样重要。
九、总结
HTTP 通信需要结合请求与响应进行理解。只掌握状态码并不足以完整定位网络问题,还需要结合请求方法、请求头、请求体、响应头、响应体以及服务器日志进行分析。
下面总结各个部分的主要作用。
HTTP 请求方法
决定客户端希望对目标资源执行什么操作,例如读取、创建、修改或删除资源。
HTTP 请求头
携带客户端信息、认证信息、缓存条件、内容协商参数和其他请求相关信息。
HTTP 请求体
承载表单、JSON、上传文件等提交内容。
HTTP 状态码
描述服务器对请求的处理结果,帮助客户端和开发人员判断请求属于成功、重定向还是错误。
HTTP 响应头
提供缓存、安全策略、资源位置、认证挑战和内容类型等信息。
HTTP 响应体
承载服务器返回的网页、JSON 数据、文件或错误说明。
最值得优先掌握的 HTTP 状态码
200 OK
请求成功。
201 Created
资源创建成功。
301 Moved Permanently
永久重定向。
302 Found
临时重定向。
304 Not Modified
资源未发生需要重新获取的变化,可以继续使用已有缓存。
307 Temporary Redirect
临时重定向,并保留原请求方法。
308 Permanent Redirect
永久重定向,并保留原请求方法。
400 Bad Request
请求格式错误或请求内容无效。
401 Unauthorized
身份认证凭据缺失或无效。
403 Forbidden
服务器拒绝执行请求。
404 Not Found
请求的资源未找到。
405 Method Not Allowed
请求方法不被目标资源允许。
429 Too Many Requests
请求过于频繁。
500 Internal Server Error
服务器内部错误。
502 Bad Gateway
网关从上游服务器收到了无效响应。
503 Service Unavailable
服务暂时不可用。
504 Gateway Timeout
网关等待上游响应超时。
在实际开发中,建议先根据状态码判断问题的大致方向,再结合请求头、响应体、浏览器 Network 面板以及服务端日志进一步分析。只有把客户端、网络、代理和后端服务放在一起观察,才能更准确地定位 HTTP 通信中的问题。
HTTP 是 Web 开发的基础知识之一。理解请求方法、请求头、响应头和状态码之间的关系,不仅有助于开发接口和排查服务器故障,也能帮助开发人员更好地理解缓存、跨域、安全策略、CDN 和搜索引擎抓取等机制。
作者声明: 本文在AI辅助下创作,最终内容经作者手动审核和修改。

评论区