1 基本概念介绍
HTTP(Hypertext Transfer Protocol)头字段是一种用于在 HTTP 报文中传递元数据的机制。在 HTTP 报文的起始行之后,头字段以键值对的形式出现,每个字段以一个唯一的名字表示。
HTTP协议的请求和响应报文中都包含HTTP头,HTTP头的内容为客户端和服务器分别处理请求和响应提供所需信息。
在 HTTP 请求中,这些头字段通常包含着请求者的信息,比如所用的浏览器、请求者接受的内容类型等等。在 HTTP 响应中,这些头字段包含着服务器返回的信息,例如响应的状态码、服务器类型以及响应头信息等等。
2 头字段分类
HTTP的头部字段类型:
- 通用头字段(General Header Fields)
请求报文和响应报文两方都会使用的首部。
- 请求头字段(Request Header Fields)
从客户端向服务器端发送请求报文时使用的头字段。补充了请求的附加内容、客户端信息、响应内容相关优先级等信息。
- 响应头字段(Response Header Fields)
从服务器端向客户端返回响应报文时使用的头字段。补充了响应的附加内容,也会要求客户端附加额外的内容信息。
- 实体头字段(Entity Header Fields)
针对请求报文和响应报文的实体部分使用的头字段。补充了资源内容更新时间等与实体有关的信息。
通用头字段包含如下:
头字段名 |
说明 |
Cache-Control |
控制缓存行为 |
Connection |
逐跳头部连接的管理 |
Date |
创建报文的日期时间 |
Pragma |
报文指令 |
Trailer |
报文末端的头部一览 |
Transfer-Encoding |
报文主体的传输编码格式 |
Upgrade |
升级为其它协议 |
Via |
代理服务器的相关信息,追踪客户端与服务器之间的请求和响应报文的传输路径。 |
请求头部字段:
头字段名 |
说明 |
Accept |
用户代理可处理的媒体类型 |
Accept-Charset |
优先的字符集 |
Accept-Encoding |
优先的内容编码 |
Accept-Language |
优先的语言(自然语言) |
Authorization |
Web认证信息 |
Expect |
期待服务器的特定行为 |
From |
说明发起请求的邮箱地址 |
Host |
请求资源所在服务器 |
If-Match |
比较实体标记(ETag) |
If-Modified-Since |
比较资源的更新时间 |
If-None-Match |
比较实体标记(与 If-Match 相反) |
If-Range |
资源未更新时发送实体 Byte 的范围请求 |
If-Unmodified-Since |
比较资源的更新时间(与If-Modified-Since相反) |
Max-Forwards |
最大传输逐跳数 |
Proxy-Authorization |
代理服务器要求客户端的认证信息 |
Range |
实体的字节范围请求 |
Referer |
对请求中 URI 的原始获取方 |
TE |
传输编码的优先级 |
User-Agent |
HTTP 客户端程序的信息 |
响应头字段:
头字段名 |
说明 |
Accept-Ranges |
是否接受字节范围请求 |
Age |
推算资源创建经过时间 |
ETag |
资源的匹配信息 |
Location |
令客户端重定向至指定URI |
Proxy-Authenticate |
代理服务器对客户端的认证信息 |
Retry-After |
对再次发起请求的时机要求 |
Server |
HTTP 服务器的安装信息 |
Vary |
代理服务器缓存的管理信息 |
WWW-Authenticate |
服务器对客户端的认证信息 |
实体头字段:
头字段名 |
说明 |
Allow |
资源可支持的HTTP方法 |
Content-Encoding |
实体主体适用的编码方式 |
Content-Language |
实体主体的自然语言 |
Content-Length |
实体主体的大小(单位:字节) |
Content-Location |
替代对应资源的URI |
Content-MD5 |
实体主体的报文摘要 |
Content-Range |
实体主体的位置范围 |
Content-Type |
实体主体的媒体类型 |
Expires |
实体主体过期的日期时间 |
Last-Modified |
资源的最后修改日期时间 |
Cookie服务的头字段:
头字段名 |
说明 |
Set-Cookie |
开始状态管理所使用的Cookie信息 响应头字段 |
Cookie |
服务器接收到的Cookie信息 请求头字段 |
扩展头字段:
X-Forwarded-For头字段:用于标记发起HTTP请求的客户端真实来源IP
X-Forwarded-Port头字段:给出客户端连接到代理上(如LB)的端口
X-Forwarded-Proto头字段:给出客户端连接到代理上的协议(http或https)
X-Forwarded-Host头字段:给出客户端发送到代理的Host标头的内容
3 典型头字段介绍
其中一些常见的 HTTP 头字段包括:
User-Agent:该字段用于识别客户端软件(类似浏览器等)的名称和版本号,以便服务器能够返回适当的内容。
Accept:该字段用于告知服务器客户端希望接收的文件类型,服务器可以根据该信息提供正确的内容。
客户端先发送Accept、Accept-Encoding、Accept-Language请求头进行协商。其中:
- Accept指明了客户端可理解的MIME type,用“,”做分隔符,列出多个类型;
- Appcep-Encoding指明客户端可理解的压缩格式;
- Accept-Languate指明客户端可理解的自然语言;
服务端会在响应头中告知协商结果:
- Content-Type:该字段表明服务端实际采用的类型。例如,如果该字段为 text/html,则表明实体是 HTML 字符串。 字段结构为:Content-Type: text/html
- Content-Encoding表示服务端实际采用的压缩格式,如果相应报文没有该请求头,则代表服务端没有开启压缩;
- Content-Language表示服务端实际采用的自然语言;
Host:该字段指定服务器的域名或 IP 地址。
Authorization:该字段包含有服务器认证的信息,用于区分获得访问资格的客户端和未获得资格的客户端。
Referer:链接的来源通常在访问链接时带有Refer字段,服务器验证来源,后台通常使用该字段作为防盗链的依据。
Cookie:一般而言,在用户登录或某些操作之后,服务器端会在返回包中包含Cookie信息,要求浏览器设置Cookie,没有Cookie很容易被识别为伪造请求。
HTTP 头字段的使用大大提高了网络应用程序的灵活性和可扩展性。不仅如此,它还可以帮助开发人员实现高效的缓存机制、数据压缩和错误处理。
4 负载均衡的头字段操作
负载均衡的七层负载,可对HTTP头字段进行操作,常用的操作如cookie、X-Forwarded-for等。
4.1 操作cookie字段实现会话保持
负载均衡通过对HTTP头中的cookie字段进行操作来实现会话保持。
- 植入cookie:客户端第一次访问时,负载均衡会在返回请求中植入Cookie(即在HTTP或HTTPS响应报文中插入ServerId),下次客户端携带此Cookie访问,负载均衡服务会将请求定向转发给之前记录到的后端服务器上。植入cookie为负载均衡添加,可在负载均衡上设置会话保持时间。
- 重写cookie:负载均衡发现用户自定义的cookie,对原来的cookie进行重写,下次客户端携带新的cookie访问,负载均衡服务将请求定向转发给之前记录到的后端服务器。重写cookie方式该cookie的会话保持时间由后端服务器维护;
4.2 通过X-Forwarded-For获取客户端真实源IP
负载均衡通常为Full NAT工作模式,客户端的访问数据包到达负载均衡后,负载均衡会将源地址替换为自身地址,目的地址根据负载均衡算法替换成一台目标主机的地址。从目标主机返回的数据包目的地址为负载均衡,负载均衡收到数据包后再把源、目的地址替换,源地址为负载均衡的VIP,目的地址为客户端地址。缺省情况下目标主机只能看到源地址为负载均衡,无法知道访问源的真实IP。 通过HTTP扩展头字段X-Forwarded-For(XFF)携带客户端源真实IP,传递给后端目标主机,可解决后端目标主机获取访问源真实地址问题。
X-Forwarded-For头字段的格式为:
X-Forwarded-For: client1, proxy1, proxy2
值通过一个 逗号+空格 把多个IP地址区分开, 最左边(client1)是最原始客户端的IP地址, 代理服务器每成功收到一个请求,就把请求来源IP地址添加到右边。如果一个HTTP 请求到达服务器之前,经过了三个代理 Proxy1、Proxy2、Proxy3,IP 分别为 IP1、IP2、IP3,用户真实 IP 为 IP0,那么按照 XFF 标准,服务端最终会收到以下信息:
X-Forwarded-For:IP0, IP1, IP2
Proxy3 直连服务器,它会给 X-Forwarded-For 追加 IP2,表示它是在帮 Proxy2 转发请求。列表中并没有 IP3,IP3 可以在服务端通过 Remote Address 字段获得。
4.3 获取客户端连接信息
X-Forwarded-Port 用于标识客户端连接负载均衡的目标端口。负载均衡对外提供的服务端口可能和后端服务器的端口不一致,可通过X-Forwarded-Port头字段携带负载均衡的服务端口信息发送给后端服务器,这样后端服务器可获取到负载均衡的服务端口信息。
X-Forwarded-Port的格式为:
X-Forwarded-Port:<port>
示例: X-Forwarded-Port:443
X-Forwarded-Proto(XFP)用来标识客户端与负载均衡之间连接所使用的传输协议。在服务端的访问日志中能够看到的是负载均衡与后端服务器之间的连接所使用的协议,而非客户端与负载均衡之间使用的协议。为了确定客户端与负载均衡之间的协议,可通过X-Forwarded-Proto来实现。
XFP头字段的格式为:
X-Forwarded-Proto:<protocol>
协议为http或https。
X-Forwarded-Host(XFH)用来标识客户端发起请求中使用Host来指定初始域名。负载均衡的域名或端口号可能会与后端的服务器不同,在这种情况下可通过X-Forwarded-Host来确定哪一个域名是最初被用来访问的。
XFH的格式为:
X-Forwarded-Host:<host>
示例:X-Forwarded-Host:app.ctyun.cn