HTTP请求头详解

前言

在 HTTP 规范里面客户端和浏览器交互是靠指令来完成的,而这些指令是放在请求头中的,请求头是以 key,value 对的形式提交参数,那些 key 都是固定的,但是有很多种,我对一些常见的 key 进行了归类整理,以下是我们常见的一个 request headers 信息(response headers 同理):

201706055380screenshot_63.png

headers 分 Request header 和 Response header,我们分别进行分析

Request header列表

Content-Type

Content-Type 里面存的是互联网媒体信息也叫 mime type,用来标识request主体里面的数据类型,常见的媒体信息列表如下:

媒体类型 应用场景
text/html 普通html文件传输
text/plain 文本传输
text/css css文件传输
text/javascript js文件传输
application/x-www-form-urlencoded request 提交form表单数据
multipart/form-data 传输文件时候会用到,表示分段传输
application/json 传输的为json字符串
application/xml 传输的为xml字符串

Content-Length

请求主体的字节长度(也就是body部分长度)

Accept

设置接收请求的content-type 如: Accept: text/plain

Accept-Charset

设置接受请求的字符集编码,如: Accept-Charset: utf-8

Accept-Encoding

设置接受的压缩编码格式,如: Accept-Encoding: gzip, deflate,和Accept-Charset不是一样的,他是对accept-charset编码后的二进制数据进行压缩采用的编码,减少数据体积,降低web服务器延时,提高web服务器性能

Accept-Language

浏览器所希望的语言种类,当服务器能够提供一种以上的语言版本时要用到

Connection

请求头发起,表示是否需要持久连接(HTTP 1.1 默认进行持久连接,Keep-Alive,Upgrade 等),因为 HTTP 协议是建立在 TCP 之上,因此也有三次握手特性,为了提高web服务器响应性能,我们可以使用 keep-alive,让浏览器能够重用已经打开的空闲持久连接,避免三次握手

Cache-Control

设置请求响应链上所有的缓存机制必须遵守的指令

请求时的缓存指令包括: no-cache、no-store、max-age、 max-stale、min-fresh、only-if-cached

响应消息中的指令包括: public、private、no-cache、no- store、no-transform、must-revalidate、proxy-revalidate、max-age

web的缓存机制非常重要,这块我还没单独测试,需要后期更新

Referer

先前网页的地址,当前请求网页紧随其后,即来路,如 Referer: http://www.zhihu.com/,表示请求是从知乎首页跳转过来的

Origin

为了防止 CSRF 的攻击,我们建议修改浏览器在发送 POST 请求的时候加上一个 Origin 字段,这个 Origin 字段主要是用来标识出最初请求是从哪里发起的。如果浏览器不能确定源在哪里,那么在发送的请求里面 Origin 字段的值就为空

1.Origin字段里只包含是谁发起的请求,并没有其他信息 (通常情况下是方案,主机和活动文档URL的端口)。跟 Referer 不一样的是,Origin 字段并没有包含涉及到用户隐私的 URL 路径和请求内容,这个尤其重要

2.按照约定,Origin 字段只存在于 POST,而Referer则存在于所有类型的请求

http://blog.sina.com.cn/s/blog_625f850801015tik.html

Authorization

设置HTTP身份验证的凭证,如 Oauth2.0 中经常就会涉及到,如,Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

HTTP 请求发送时,会把保存在该请求域名下的所有 cookie 值一起发送给web服务器。如 Cookie: $Version=1; Skin=new;

Host

指定请求的服务器的域名和端口号 Host: www.zhihu.com

User-Agent

User-Agent 的内容包含发出请求的用户信息,User-Agent: Mozilla/5.0 (Linux; X11),表示是 Linux 操作系统中的火狐浏览器发出的

X-Forwarded-For

这是一个标示 http 代理情况的请求头字段,格式如下 X-Forwarded-For: client, proxy1, proxy2,其中 client 代表客户端 ip,proxy1,proxy2 等代表客户端到服务端过程中经过的 proxy 的 ip 地址,其中最后一个 proxy 代表请求直连服务器

Response header列表

Content-MD5

返回资源的MD5校验值,如:Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ==

Expires

响应过期的日期和时间 ,如 Expires: Thu, 01 Dec 2010 16:00:00 GMT

设置Http Cookie,如 Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1

Content-Length

响应体的长度通常配合http持久连接使用。对于非持久连接,浏览器可以通过连接是否关闭来界定请求和响应实体的边界;而对于持久连接,这种方法显然不奏效,因此就需要服务端在响应头里面标示一个body长度,方便客户端知道数据是否传完了

Content-Type

返回内容的MIME类型和字符集编码 Content-Type: text/html; charset=utf-8

Content-Encoding

web服务器支持的返回内容压缩编码类型 Content-Encoding: gzip,一般文本文件会需要压缩编码,图片因为本来就是高压缩的所以不再需要

Transfer-Encoding

文件传输分块编码,通常在传输大文件的时候使用,如图片等。使用样例: Transfer-Encoding:chunked,表示分块编码传输,他和 Content-Encoding 同为http中编码相关的请求头,可以一起用,表示对每一块进行单独压缩。

注意:当使用 Transfer-Encoding 的时候因为比较底层,会影响实际body长度(增大),所以此时 Content-Encoding 就会被浏览器忽略,界定请求和响应实体边界的事就落到了 Transfer-Encoding 的头上,每个分块包含十六进制的长度值和数据,长度值独占一行,长度不包括它结尾的 CRLF(\r\n),也不包括分块数据结尾的 CRLF。最后一个分块长度值必须为 0,对应的分块数据没有内容,表示实体结束,界定请求和响应实体边界

Location

用来重定向接收方到非请求URL的位置来完成请求或标识新的资源如:Location: http://www.zcmhi.com/archives/94.html

用于服务端告诉浏览器不要通过任何不安全的渠道发送cookie(只在https协议下发送cookies),从而保证了敏感会话暗号(token)一定是经过加密处理才发生的

HttpOnly

用于指示浏览器禁止任何脚本访问 cookies 内容,这样可以降低 js 偷取 cookies

Content-Security-Policy

CSP 的实质就是白名单制度,开发者明确告诉客户端,哪些外部资源可以加载和执行,等同于提供白名单

X-Content-Type-Options

对于客户端返回的数据,如果 content-type 是未知会触发浏览器的自动检测机制去自主判断文件类型并执行,该选项就是禁用该功能。当用户上传了某段恶意 js 代码组成的文件,又被其他用户当作图片文件下载,但是又没告诉浏览器文件类型,这次浏览器会误认为这是一个 js 文件并执行

strict-Transport-Security

指示浏览器必须通过有效的 HTTPS 通信与网站通信

X-Frame-Options

用于阻止浏览器中的 iframe 内页嵌套问题,防止一部分界面伪装攻击,如透明页面覆盖引起的点击劫持

补充

理解 http 无状态

http 无状态我们通常说的是 http 协议层的无状态,服务器在处理不同 http 请求的时候不需要去处理不同请求之间的关系和依赖。而在应用层 http 是有状态的,我们通常将每一个 http 请求都会记录到一次会话中,会话有之对应的会话 id,专门用于追踪用户请求之间的关系,这些会话信息,我们可以存到 localstorage 或者 cookies,session 中,方便服务端记录用户状态

附录

附上两种维基百科的总结

https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Request_fields

https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Response_fields

坚持原创技术分享,您的支持将鼓励我继续创作!