每个 Web 开发者都应了解的 HTTP 标头
摘要
探索不同类型的 HTTP 标头,包括请求、响应、CORS、缓存、安全、内容协商、条件、实体等。
HTTP 标头控制着浏览器和服务器的交互方式。它们处理着一些基本任务,如识别内容类型、管理身份验证、设置缓存策略、控制重定向和强制执行跨域规则。它们还允许开发人员在不同场景下自定义 API 的响应方式。
本文将解释 HTTP 标头的类型以及如何在开发过程中使用它们。
什么是 HTTP 标头?
HTTP 标头是在每次 Web 请求和响应期间在浏览器和服务器之间发送的键值对。它们帮助双方了解如何处理请求或传递响应。
标头携带的详细信息包括:正在发送的内容类型、应缓存多长时间、首选语言是什么,或者用户是否有权访问内容。这些额外的上下文信息使 Web 通信更可靠、更安全、更高效。
为什么 HTTP 标头在 Web 开发中很重要
标头在塑造网站功能、通信和保护用户数据方面至关重要。它们帮助开发人员控制行为、执行标准和提高性能。
- 内容识别: 像
Content-Type这样的标头定义了正在传输的数据类型。这有助于浏览器了解是应该呈现 HTML、解析 JSON 还是下载文件。 - 用户身份验证:
Authorization标头用于发送凭据或令牌,允许用户访问应用程序的安全部分,而无需重复登录。 - 缓存和负载管理: 诸如
Cache-Control或ETag之类的标头可帮助浏览器在可能的情况下存储和重用内容。这减少了服务器负载,并为回头客缩短了页面加载时间。 - 跨域访问控制: 跨域资源共享 (CORS) 标头指定了允许哪些外部网站访问您的资源。这对于 API 和公共内容至关重要。
- 语言和编码首选项: 像
Accept-Language或Content-Encoding这样的标头让开发人员可以根据用户偏好或连接类型来定制响应,例如提供压缩内容以节省带宽。 - 请求跟踪和日志记录: 诸如
User-Agent或Referer之类的标头提供了有关请求来源以及正在使用的浏览器或设备的信息。这有助于调试、分析和个性化。
HTTP 标头的类型
HTTP 标头根据其在请求-响应周期中的使用时间和方式进行分组。了解这些类别有助于正确组织标头并避免配置错误。
- 通用标头:它们包含不特定于内容的信息,例如连接状态或缓存策略,并适用于请求和响应。例如,
Cache-Control告诉浏览器缓存响应需要多长时间。 - 请求标头:它们告诉服务器客户端需要、支持或偏好什么,并从浏览器发送到服务器。例如,
Accept指定了首选的内容类型,如 JSON 或 HTML,而User-Agent则标识了浏览器和操作系统。 - 响应标头:它们从服务器发送到浏览器,并描述响应,例如其格式或长度。例如,
Content-Type告诉浏览器如何解释数据,如 HTML、JSON 或纯文本。 - 实体标头:它们提供有关请求或响应正文的详细信息,例如其大小或编码。例如,
Content-Length显示正文中有多少字节,而Content-Encoding则指示内容是否被压缩。 - 端到端标头:无论涉及多少中介,这些标头都从客户端到服务器或反之亦然地保持不变。例如,即使使用代理,
Authorization也会保持不变。 - 逐跳标头:这些标头仅由单个传输级连接处理,不会被代理转发。例如,
Connection控制网络连接在当前事务后是否保持打开状态。
常见的请求标头
请求标头由浏览器发送到服务器。它们描述了客户端可以接受什么、用户是谁,或者应该如何处理请求。
- Authorization:用于发送令牌或 API 密钥等凭据,以便服务器可以验证请求。例如,REST API 可能需要
Authorization: Bearer <token>才能允许访问用户数据。 - Accept:告诉服务器客户端可以处理什么类型的内容。例如,
Accept: application/json告诉服务器以 JSON 而不是 HTML 的形式返回数据。 - Accept-Encoding:列出客户端支持的压缩格式。例如,
Accept-Encoding: gzip, br允许服务器使用 gzip 或 Brotli 压缩响应以减小大小。 - Accept-Language:指定响应内容的首选语言。例如,
en-US告诉服务器如果支持,则以美式英语返回响应。 - User-Agent:描述发出请求的浏览器和系统。例如,移动浏览器可能会发送一个
User-Agent,以帮助服务器提供移动优化的布局。 - Referer 和 Referrer-Policy:
Referer发送前一个页面的 URL,通常用于分析或安全过滤器。Referrer-Policy控制是否发送该信息,有助于减少敏感 URL 的泄露。 - Cookie:将存储的数据(如会话 ID 或用户偏好)从浏览器发送到服务器。例如,
Cookie: session_id=abc123允许服务器识别用户并维持其会话,而无需他们再次登录。
常见的响应标头
当服务器向浏览器发送响应时,它会包含描述内容以及应如何处理内容的标头。这些标头控制着重定向、内容类型和会话管理等行为。
以下是一些最常用的响应标头:
Set-Cookie:在用户设备上保存一个 cookie,以便服务器可以识别回访用户或存储会话数据。例如,
Set-Cookie: session_id=abc123可帮助服务器识别已登录的用户,而无需他们再次登录。Location:告诉浏览器将用户重定向到不同的 URL。这通常在表单提交后或访问受限时使用。例如,
Location: /login会在用户尝试访问受限区域时将其发送到登录页面。WWW-Authenticate:指示浏览器在访问资源之前要求用户提供凭据。例如,
WWW-Authenticate: Basic会触发一个要求输入用户名和密码的登录提示。Content-Type:描述返回内容的格式,以便浏览器可以正确处理它。例如,
Content-Type: application/json告诉浏览器响应包含一个 JSON 对象。Content-Length:指定响应正文的大小(以字节为单位)。这有助于浏览器知道响应何时已完全接收。例如,
Content-Length: 4523告诉浏览器期望 4,523 字节的数据。Content-Encoding:告诉浏览器内容是如何被压缩的,以便它知道如何解码。例如,
Content-Encoding: gzip告诉浏览器在显示数据之前先解压缩数据。Content-Language:指示服务器返回的内容的语言。
例如,
Content-Language: en-US表示内容为美式英语。Content-Disposition:指示浏览器如何处理响应——是显示它还是下载它。
例如,
Content-Disposition: attachment; filename="invoice.pdf"会触发一个 PDF 文件的下载提示。
缓存标头
缓存标头可帮助浏览器和服务器管理资源的存储副本。这通过避免在内容未更改时不必要的下载来减少加载时间和服务器流量。
以下是用于缓存控制的一些关键标头:
Cache-Control:定义缓存规则,例如响应可以存储多长时间,或者是否必须重新验证。例如,
Cache-Control: max-age=3600允许浏览器在一小时内重用该响应。Pragma:一个在 HTTP/1.0 中禁用缓存的旧标头。例如,
Pragma: no-cache告诉旧版浏览器不要缓存响应。Expires:设置一个特定的日期和时间,在此之后响应被视为过时。例如,
Expires: Wed, 21 Jun 2025 07:28:00 GMT将该日期标记为缓存到期时间。ETag:为响应版本提供一个唯一标识符,以检查内容是否已更改。例如,
ETag: "abc123"让浏览器可以询问服务器该版本是否仍然有效。Last-Modified:指示资源上次更改的时间。例如,
Last-Modified: Tue, 11 Jun 2024 10:00:00 GMT可帮助浏览器决定是否获取新版本。If-Modified-Since:由浏览器发送,以检查内容自给定日期以来是否已更改。例如,
If-Modified-Since: Tue, 11 Jun 2024 10:00:00 GMT可避免在数据未更改时下载数据。Vary:指示浏览器根据标头值缓存响应的不同版本。例如,
Vary: Accept-Encoding告诉缓存为 gzip 和非 gzip 请求存储单独的副本。Age:显示响应已在代理缓存中存储了多长时间。例如,
Age: 120表示响应已被缓存 120 秒。Clear-Site-Data:告诉浏览器删除站点的存储数据,如缓存或 cookie。例如,
Clear-Site-Data: "cache", "cookies"会删除所有缓存的文件和会话数据。
安全标头
安全标头可保护用户免受常见的 Web 漏洞的侵害。它们指导浏览器强制执行特定的安全规则,有助于防止跨站脚本 (XSS)、点击劫持和混合内容等攻击。以下是用于加强站点安全性的关键标头:
Strict-Transport-Security:强制浏览器在所有未来请求中都使用 HTTPS 而不是 HTTP。例如,
Strict-Transport-Security: max-age=31536000告诉浏览器在接下来的一年中使用 HTTPS。Content-Security-Policy:控制浏览器可以从哪些来源加载内容,以降低 XSS 风险。例如,
Content-Security-Policy: default-src 'self'会阻止来自不受信任域的资源。X-Content-Type-Options:防止浏览器猜测内容类型,这可以阻止某些攻击。例如,
X-Content-Type-Options: nosniff确保文件仅被解释为其声明的类型。X-Frame-Options:控制站点是否可以嵌入到 iframe 中,以防止点击劫持。例如,
X-Frame-Options: DENY会阻止站点在任何 iframe 中加载。X-XSS-Protection:曾用于启用内置的浏览器保护,以抵御反射型 XSS 攻击。例如,
X-XSS-Protection: 1; mode=block告诉浏览器阻止可疑脚本(现在在大多数现代浏览器中已弃用)。Expect-CT:告诉浏览器强制执行证书透明度,从而提高 SSL 安全性。
例如,
Expect-CT: max-age=86400, enforce会阻止未在公共日志中列出的证书。Cross-Origin-Resource-Policy:限制其他站点加载您资源的方式,以防止数据泄露。例如,
Cross-Origin-Resource-Policy: same-origin确保资源仅在同一来源内共享。Feature-Policy (现为 Permissions-Policy):限制对浏览器功能(如摄像头或地理位置)的访问。例如,
Permissions-Policy: camera=(), microphone=()会阻止摄像头和麦克风的访问。Upgrade-Insecure-Requests:要求浏览器自动将 HTTP 资源升级到 HTTPS。例如,
Upgrade-Insecure-Requests: 1告诉浏览器在加载任何 HTTP 资源之前先尝试 HTTPS。
CORS 标头
CORS(跨域资源共享)标头控制着不同来源之间如何共享资源。它们通过定义哪些域可以访问您的 API 以及在什么条件下访问来帮助保护您的应用程序。
以下是管理 CORS 行为的标头:
Access-Control-Allow-Origin:指定允许哪个来源访问资源。例如,
Access-Control-Allow-Origin: https://example.com仅允许来自该域的请求。Access-Control-Allow-Credentials:指示请求中是否可以包含 cookie 或凭据。例如,
Access-Control-Allow-Credentials: true允许浏览器随请求发送 cookie。Access-Control-Allow-Headers:列出客户端允许请求的标头。例如,
Access-Control-Allow-Headers: Authorization, Content-Type允许在请求中使用这两个标头。Access-Control-Allow-Methods:指定在发出跨域请求时允许使用哪些 HTTP 方法。例如,
Access-Control-Allow-Methods: GET, POST, PUT允许服务器接受来自允许来源的这些方法。Access-Control-Expose-Headers:指定 JavaScript 可以读取哪些响应标头。例如,
Access-Control-Expose-Headers: X-Custom-Header使该标头在前端代码中可用。Access-Control-Request-Headers:这些由浏览器在预检请求期间发送,以检查实际请求中是否可以包含自定义标头。例如,
Access-Control-Request-Headers: Authorization告诉服务器客户端想要发送一个Authorization标头,服务器必须在 CORS 策略中批准该标头。Access-Control-Request-Method:由浏览器发送,以询问它可以使用哪种 HTTP 方法。例如,在发送实际的 PUT 请求之前使用
Access-Control-Request-Method: PUT。Origin:标识请求的来源,以便服务器可以决定是否允许它。例如,
Origin: https://example-client.com显示请求的来源。Timing-Allow-Origin:指定允许哪些来源访问资源的详细计时信息。例如,
Timing-Allow-Origin: *允许所有来源查看性能指标,如响应时间和网络延迟。
优化和客户端提示
这些标头可帮助浏览器与服务器共享设备和网络信息,以优化内容交付和性能。它们对于响应式设计和高效的资源加载非常方便。
- Accept-CH:告诉浏览器服务器希望在未来的请求中包含哪些客户端提示。例如,
Accept-CH: DPR, Viewport-Width有助于为不同设备定制图像。 - Save-Data:表示用户偏好减少数据使用量。例如,
Save-Data: on有助于服务器发送分辨率较低的图像或较少的脚本。 - DPR:代表设备像素比,并告知服务器屏幕密度。例如,
DPR: 2.0表示设备具有高分辨率显示屏。 - Viewport-Width:提供布局视口的宽度(以像素为单位)。例如,
Viewport-Width: 360允许服务器发送适合移动屏幕大小的内容。 - Width:指示所请求图像的理想宽度。例如,
Width: 720有助于服务器选择或生成适合的图像。 - Device-Memory:共享设备上有多少可用的 RAM。例如,
Device-Memory: 4表示设备有 4 GB 的 RAM。 - Early-Data:表示请求是否在 TLS 握手完成之前发送。例如,
Early-Data: 1有助于避免 HTTP/2 或 0-RTT 中的重放风险。
代理和连接标头
这些标头控制请求如何通过代理,或管理客户端和服务器之间的连接设置。它们在具有多层(如负载均衡器或 CDN)的环境中尤其重要。
- Connection:控制网络连接是否保持打开。例如,
Connection: keep-alive保持 TCP 连接打开以供重用。 - Keep-Alive:与
Connection标头一起设置连接保持打开的时间。例如,Keep-Alive: timeout=5, max=100定义了 5 秒的超时时间和 100 次最大请求数。 - Forwarded:通过代理共享原始请求详细信息的标准化方式。例如,
Forwarded: for=192.0.2.43; proto=https告诉服务器谁发出了请求以及如何发出的。 - Via:列出请求通过的代理。例如,
Via: 1.1 proxy1.example.com有助于调试代理链。 - X-Forwarded-For:标识客户端的原始 IP 地址。例如,
X-Forwarded-For: 203.0.113.1显示代理背后的真实 IP。 - X-Forwarded-Host:共享客户端请求的原始主机。例如,
X-Forwarded-Host: www.example.com有助于在代理后面恢复正确的 URL。 - X-Forwarded-Proto:告知原始请求是使用 HTTP 还是 HTTPS。例如,
X-Forwarded-Proto: https允许应用程序在需要时安全地重定向。
范围和条件标头
这些标头有助于控制部分内容交付或确定内容是否已更改。它们对于高效的数据传输至关重要,尤其是在处理大文件或重复请求时。
- Range:请求资源的特定部分。例如,
Range: bytes=0-499请求文件的前 500 个字节。 - Accept-Ranges:告诉客户端是否支持部分请求。例如,
Accept-Ranges: bytes表示服务器接受范围请求。 - Content-Range:在响应中发送,以显示交付了资源的哪个部分。例如,
Content-Range: bytes 0-499/1234表示一个 1234 字节文件中的 500 字节。 - If-Range:结合了条件请求和范围请求。例如,
If-Range: "abc123"确保仅在资源未更改时才发送部分响应。 - If-Match:仅当资源与给定的 ETag 匹配时才发送请求。例如,
If-Match: "xyz789"可防止覆盖已更新的文件。 - If-None-Match:告诉服务器仅当 ETag 不匹配时才响应。例如,
If-None-Match: "xyz789"有助于避免下载未更改的内容。 - If-Modified-Since:仅当资源在给定日期之后已更新时才请求该资源。例如,
If-Modified-Since: Tue, 11 Jun 2024 10:00:00 GMT。 - If-Unmodified-Since:这与上述相反,它仅在内容未更改时才处理请求。例如,
If-Unmodified-Since: Tue, 11 Jun 2024 10:00:00 GMT。
WebSocket 和流式处理标头
这些标头支持像 WebSocket 这样的协议,或启用流式内容,即以块的形式发送数据,而不是一次性全部发送。它们对于实时应用程序或大文件传输非常有用。
- Sec-WebSocket-Accept: 在 WebSocket 握手期间用于确认连接有效。例如,
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=是服务器对 WebSocket 升级请求的响应。 - Transfer-Encoding: 定义响应正文的格式或分块方式。例如,
Transfer-Encoding: chunked在不知道完整大小的情况下分段发送数据。 - TE:指示客户端支持的传输编码类型。例如,
TE: trailers告诉服务器客户端可以接受分块响应末尾的附加标头。 - Trailer: 列出将出现在分块消息末尾的标头。例如,
Trailer: Expires告诉客户端在正文之后会有一个Expires标头。
如何在浏览器中查看和测试标头
您可以在浏览器中检查和测试标头,以调试问题、验证配置或确认在预生产或生产环境中的行为。
- 使用开发工具查看标头: 在 Chrome 或 Firefox 中,打开开发工具 (F12),转到 网络 选项卡,然后重新加载页面。选择任何请求以查看详细的请求和响应标头。
- 无需更改代码即可测试标头: 使用像 Requestly 这样的浏览器工具来覆盖或注入实时页面上的标头。这有助于在不接触后端代码的情况下模拟不同的场景。
Requestly 如何帮助处理 HTTP 标头?
Requestly 的 修改 HTTP 标头 功能允许开发人员在开发或测试期间控制 HTTP 请求和响应标头,而无需更改任何后端代码。它直接在浏览器中工作,并支持简单和高级的用例。以下是其主要功能:
- 添加、删除或覆盖标头:您可以自由修改请求或响应中的任何标头字段,例如添加
Authorization、删除X-Frame-Options或更改User-Agent。 - 绕过 CORS 限制:插入或更改与 CORS 相关的标头,如
Access-Control-Allow-Origin、Access-Control-Allow-Headers和Access-Control-Allow-Methods,以避免在本地测试期间出现浏览器端的 CORS 错误。 - 模拟经过身份验证的会话:自动添加诸如
Authorization: Bearer <token>之类的标头,以测试受保护的 API 或模拟用户会话,而无需登录。 - 注入自定义标头以进行功能测试:使用诸如
x-user-id或x-feature-flag之类的标头来模拟不同用户、状态或跨页面的功能访问条件。 - 移除安全限制:禁用诸如
Content-Security-Policy或X-Frame-Options之类的标头,以允许 iframe 嵌入或在限制性环境中测试自定义脚本。 - 测试第三方行为:修改传出请求中的标头,以测试外部 API、CDN 或其他服务在不同条件下的响应方式。
使用标头的最佳实践
这些最佳实践有助于防止出现性能、安全性和浏览器兼容性问题。
- 避免不必要的标头:不要包含对您的应用程序没有影响或未使用的标头。它们会增加请求大小并增加噪音。
- 保护敏感信息:除非绝对必要且安全,否则切勿在标头中暴露令牌、API 密钥或内部服务器信息。
- 对 CORS 规则要具体:避免对敏感端点使用像
*这样的通配符。明确定义允许的来源和方法。 - 始终设置正确的 Content-Type:这有助于浏览器正确解释响应,并防止表单提交或 JSON 解析问题。
结论
HTTP 标头塑造了内容在整个网络中的交付、缓存、保护和个性化方式。它们还影响登录状态、访问控制、语言偏好和 API 行为,使其对于任何现代 Web 应用程序都至关重要。
