https://segmentfault.com/a/1190000018234763

HTTP 消息头允许客户端和服务器通过 request response传递附加信息。一个请求头由名称(不区分大小写)后跟一个冒号“:”,冒号后跟具体的值(不带换行符)组成。该值前面的引导空白会被忽略。
自定专用消息头可通过’X-‘ 前缀来添加;但是这种用法被IETF在2012年6月发布的 RFC6648 中明确弃用,原因是其会在非标准字段成为标准时造成不便;其他的消息头在 IANA 注册表 中列出, 其原始内容在 RFC 4229 中定义。 此外,IANA 还维护着被提议的新HTTP 消息头注册表.
根据不同上下文,可将消息头分为:

  • General headers: 同时适用于请求和响应消息,但与最终消息主体中传输的数据无关的消息头。
  • Request headers: 包含更多有关要获取的资源或客户端本身信息的消息头。
  • Response headers: 包含有关响应的补充信息,如其位置或服务器本身(名称和版本等)的消息头。
  • Entity headers: 包含有关实体主体的更多信息,比如主体长(Content-Length)度或其MIME类型。

消息头也可以根据代理对其的处理方式分为:

1、HTTP 请求内容

因为最新的http2,并无被各大浏览器普遍使用,因此本文是基于http/1.1所编写的。
同时通过检测咱们也发现,chrome等浏览器也正是使用http/1.1版本的。html
HTTP Headers - 图2
关于http/1.1协议的详情,可查看官方文档web
咱们打开chrome的network,点击任何一条request请求,便可发现,每一个http headers都包含如下部分:Genaral,Request Headers,Response Headers,Request Payload。算法
General(不属于headers,只用于收集请求url和响应的status等信息)
HTTP Headers - 图3chrome
Request Headers(请求headers)
HTTP Headers - 图4后端
Response Headers(响应headers)
HTTP Headers - 图5跨域
Request Payload(请求参数)浏览器

HTTP Headers - 图6

2、HTTP Headers分类

在http heanders中,为了方便,分为如下几类:Genaral headers(和上面说的General不一样,这个只是为了方便统计),Request Headers,Response Headers,Entity Headers(也是为了方便统计)。缓存
HTTP Headers - 图7
因此,一个完整的请求头/响应头,应该除了自身,还包括 General Headers和Entity Headers。
HTTP Headers - 图8安全
一、Genaral headers: 同时适用于请求和响应消息,但与最终消息传输的数据无关的消息头。
二、Request Headers: 包含更多有关要获取的资源或客户端自己信息的消息头。
三、Response Headers:包含有关响应的补充信息,如其位置或服务器自己(名称和版本等)的消息头。
四、Entity Headers:包含有关实体主体的更多信息,好比主体长(Content-Length)度或其MIME类型。

一、Genaral headers

Cache-Control——控制缓存的行为; 详情
Connection——决定当前的事务完成后,是否会关闭网络链接; 详情
Date——建立报文的日期时间; 详情
Keep-Alive——用来设置超时时长和最大请求数; 详情
Via——代理服务器的相关信息; 详情
Warning——错误通知; 详情
Trailer——容许发送方在分块发送的消息后面添加额外的元信息; 详情
Transfer-Encoding——指定报文主体的传输编码方式; 详情
Upgrade——升级为其余协议;

二、Request headers

Accept——客户端能够处理的内容类型; 详情
Accept-Charset——客户端能够处理的字符集类型; 详情
Accept-Encoding——客户端可以理解的内容编码方式; 详情
Accept-Language——客户端能够理解的天然语言; 详情
Authorization——Web 认证信息; 详情
Cookie——经过Set-Cookie设置的值; 详情
DNT——代表用户对于网站追踪的偏好; 详情
From——用户的电子邮箱地址; 详情
Host——请求资源所在服务器; 详情
If-Match——比较实体标记(ETag); 详情
If-Modified-Since——比较资源的更新时间; 详情
If-None-Match——比较实体标记(与 If-Match 相反); 详情
If-Range——资源未更新时发送实体 Byte 的范围请求; 详情
If-Unmodified-Since——比较资源的更新时间(与 If-Modified-Since 相反); 详情
Origin——代表了请求来自于哪一个站点; 详情
Proxy-Authorization——代理服务器要求客户端的认证信息; 详情
Range——实体的字节范围请求; 详情
Referer——对请求中 URI 的原始获取方; 详情
TE——指定用户代理但愿使用的传输编码类型; 详情
Upgrade-Insecure-Requests——表示客户端优先选择加密及带有身份验证的响应; 详情
User-Agent——浏览器信息; 详情

三、Response Headers

Accept-Ranges——是否接受字节范围请求; 详情
Age——消息对象在缓存代理中存贮的时长,以秒为单位; 详情
Clear-Site-Data——表示清除当前请求网站有关的浏览器数据(cookie,存储,缓存); 详情
Content-Security-Policy——容许站点管理者在指定的页面控制用户代理的资源; 详情
Content-Security-Policy-Report-Only—— 详情
ETag——资源的匹配信息; 连接描述
Location——令客户端重定向至指定 URI; 详情
Proxy-Authenticate——代理服务器对客户端的认证信息; 详情
Public-Key-Pins——包含该Web 服务器用来进行加密的 public key (公钥)信息; 详情
Public-Key-Pins-Report-Only——设置在公钥固定不匹配时,发送错误信息到report-uri; 详情
Referrer-Policy——用来监管哪些访问来源信息——会在 Referer 中发送; 详情
Server——HTTP 服务器的安装信息; 详情
Set-Cookie——服务器端向客户端发送 cookie; 详情
Strict-Transport-Security——它告诉浏览器只能经过HTTPS访问当前资源; 详情
Timing-Allow-Origin——用于指定特定站点,以容许其访问Resource Timing API提供的相关信息; 详情
Tk——显示了对相应请求的跟踪状况; 详情
Vary——服务器缓存的管理信息; 详情
WWW-Authenticate——定义了使用何种验证方式去获取对资源的链接; 详情
X-XSS-Protection——当检测到跨站脚本攻击 (XSS)时,浏览器将中止加载页面; 详情

四、Entity Headers

Allow——客户端能够处理的内容类型,这种内容类型用MIME类型来表示; 详情
Content-Encoding——用于对特定媒体类型的数据进行压缩; 详情
Content-Language——访问者但愿采用的语言或语言组合; 详情
Content-Length——发送给接收方的消息主体的大小; 详情
Content-Location——替代对应资源的 URI; 详情
Content-Range——实体主体的位置范围; 详情
Content-Type——告诉客户端实际返回的内容的内容类型; 详情
Expires——包含日期/时间, 即在此时候以后,响应过时; 详情
Last-Modified——资源的最后修改日期时间; 详情

3、HTTP 具体应用

一、Cookie

HTTP 协议是无状态的,主要是为了让 HTTP 协议尽量简单,使得它可以处理大量事务。HTTP/1.1 引入 Cookie 来保存状态信息。服务器
Cookie 是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器以后向同一服务器再次发起请求时自动被携带上,用于告知服务端两个请求是否来自同一浏览器。因为以后每次请求都会须要携带 Cookie 数据,所以会带来额外的性能开销(尤为是在移动环境下)。
Cookie 曾一度用于客户端数据的存储,由于当时并无其它合适的存储办法而做为惟一的存储手段,但如今随着现代浏览器开始支持各类各样的存储方式,Cookie 渐渐被淘汰。新的浏览器 API 已经容许开发者直接将数据存储到本地,如使用 Web storage API(本地存储和会话存储)或 IndexedDB。

a、建立过程

服务器发送的响应报文包含Set-Cookie首部字段,客户端获得响应报文后把 Cookie 内容保存到浏览器中。
HTTP/1.1 200 OK Content-type: text/html Set-Cookie: PHPSESSID=kq8v6iujarsgflkeq7shmai9c7
客户端以后对同一个服务器发送请求时,会从浏览器中取出 Cookie 信息并经过 Cookie 请求首部字段发送给服务器。
GET /sample_page.html HTTP/1.1 Host: www.example.org Cookie: PHPSESSID=kq8v6iujarsgflkeq7shmai9c7

b、分类

会话期 Cookie:浏览器关闭以后它会被自动删除,也就是说它仅在会话期内有效。
持久性 Cookie:指定一个特定的过时时间(Expires)或有效期(max-age)以后就成为了持久性的 Cookie。
安全 Cookie:指定HttpOnly,这样cookie不能使用 JavaScript 经由 Document.cookie 属性,来防范跨站脚本攻击(XSS)。
HTTPS Cookie: 指定Secure,只有在请求使用SSL和HTTPS协议的时候才会被发送到服务器。
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;HttpOnly Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;Secure

二、缓存

下降客户端获取资源的延迟:缓存一般位于内存中,读取缓存的速度更快。而且缓存在地理位置上也有可能比源服务器来得近,例如浏览器缓存(可是只能缓存get,不能缓存其余类型请求)。
cache FAQ MDN
流程图:
HTTP Headers - 图9

a、判断cache-control或者expires是否有效

HTTP Headers - 图10
max-age值为缓存的毫秒数。
能够看到response-headers中设置了cache-control,并大于0,则下次直接从缓存(from disk cache)中获取

b、Etag判断

当发现Cache-Control设置的毫秒数过时了,则直接发送请求:
——若是响应中包含Etag(服务器生成的值),则浏览器再次向web服务器发送请求并带上头If-None-Match(Etag的值),web服务器收到请求后发现有头If-None-Match 则与被请求资源的相应校验串进行比对,决定返回200或304(浏览器会从缓存中获取)。
——若是响应中不包含Etag,则进行Last-Modified判断

c、Last-Modified判断

当发现response header中含有Last-Modified,则再次向web服务器请求时带上头 If-Modified-Since,web服务器收到请求后发现有头If-Modified-Since 则与被请求资源的最后修改时间进行比对,而后服务器决定返回200或者304(缓存)
浏览器强制告诉服务器不缓存资源:
//request headers Cache-Control:max-age=0, no-cache

4、HTTP 请求 method

5、HTTP 状态码

HTTP Headers - 图11

一、1XX

  • 100(continue) 代表到目前为止都很正常,客户端能够继续发送请求或者忽略这个响应。

    二、2XX

  • 200(OK) 表示从客户端发来的请求在服务器端被正常处理了。

  • 204(No Content) 该状态码表明服务器接收的请求已成功处理,但在返回的响应报文中不含实体的主体部分。
  • 206(Partial Content) 该状态码表示客户端进行了范围请求,而服务器成功执行了这部分的 GET 请求。响应报文中包含由 Content-Range 指定范围的实体内容。

    三、3XX

  • 301(Moved Permanently) 永久性重定向。该状态码表示请求的资源已被分配了新的 URI,之后应使用资源如今所指的 URI。

  • 302(Found) 临时性重定向。好比在没有登陆状况下访问网站”我的中心”,会重定向到登陆页,可是你登陆后,访问我的中心时,它又不会重定向到其余地方了。
  • 303(See Other) 和 302 有着相同的功能,可是 303 明确要求客户端应该采用 GET 方法获取资源。
  • 304(Not Modified) 若是请求报文首部包含一些条件,例如:If-Match,If-Modified-Since,If-None-Match,If-Range,If-Unmodified-Since,若是不知足条件,则服务器会返回 304 状态码。

    四、4XX

  • 400(Bad Request) 该状态码表示请求报文中存在语法错误。当错误发生时,需修改请求的内容后再次发送请求。

  • 401 Unauthorized 该状态码表示发送的请求须要有认证信息。返回含有 401 的响应必须包含一个适用于被请求资源的 WWW-Authenticate 首部用以询问用户信息。当浏览器初次接收到 401 响应,会弹出认证用的对话窗口。第二次接收到,则不弹出,直接表示认证失败。
  • 403(Forbidden) 对请求资源的访问被服务器拒绝了,通常是未得到文件系统的访问受权,问权限出现某些问题。
  • 404(Not Found) 浏览器地址错误。服务器找不到对应资源。

    五、5XX

  • 500(Internal Server Error) 服务器在执行时报错。

  • 503(Service Unavailable) 服务器暂时处于超负载或正在进行停机维护,无响应。通常须要重启服务器便可。

    6、MIME类型

    浏览器一般使用MIME类型(而不是文件扩展名)来肯定如何处理文档;所以设置正确的MIME类型附加到headers是很是重要的。
    HTTP Headers - 图12
    除了上面的基本的5中类型外,还有一种类型,即multipart类型。
    multipart/form-data 在表单中经过post上传
    multipart/byteranges (不经常使用,不知道)
    通常的,若是没有显示的在request headers的Allow上设置类型,浏览器的MIME 嗅探会推测出来对应的类型,若是发现找不到特定的子类型,则给出默认类型,好比对于text文件类型若没有特定的subtype,就使用 text/plain。相似的,二进制文件没有特定或已知的 subtype,即便用 application/octet-stream。

    7、HTTP 使用的认证方式

    一、BASIC 认证(基本认证)
    二、DIGEST 认证(摘要认证)
    三、SSL 客户端认证
    四、FormBase 认证(基于表单认证)

    一、BASIC 认证

    当在浏览器端输入一个url时,会自动弹出一个框,要求输入用户名和密码。此种方式为basic认证。
    下面是认证执行过程:
    第一步:在浏览器地址栏中输入 http://localhost:8080/auth
    第二步: 服务器执行,发现须要认证,返回这个请求的响应。并在response headers中添加WWW-Authenticate,将http请求状态设置为401.
    HTTP Headers - 图13
    浏览器检测到WWW-Authenticate为basic后,自动弹出框。
    HTTP Headers - 图14
    第三步: 当用户看到框后,输入 用户名和密码,浏览器会将用户名和密码经过base64方式编码,而后添加到 request headers的 Authorization 中发送给服务器,浏览器验证经过,返回200状态码
    HTTP Headers - 图15
    若是验证不经过,则继续返回状态码401,提示验证失败。
    HTTP Headers - 图16
    缺点:
    BASIC 认证虽然采用 Base64 编码方式,但这不是加密处理。不须要任何附加信息便可对其解码。换言之,因为明文解码后就是用户 ID和密码,在 HTTP 等非加密通讯的线路上进行 BASIC 认证的过程当中,若是被人窃听,被盗的可能性极高。

    二、DIGEST 认证

    为了弥补Basic认证没有加密所带来的不安全性,出现了DIGEST 认证。
    过程以下:
    第一步:在浏览器地址栏中输入 http://localhost:8080/auth
    第二步: 服务器执行,发现须要认证,返回这个请求的响应。并在response headers中添加WWW-Authenticate(包含有随机码nonce),将http请求状态设置为401.
    浏览器检测到WWW-Authenticate为 digest 后,自动弹出框。
    第三步: 当用户看到框后,输入 用户名和密码,浏览器会将用户名和上步返回的nouce,添加到 request headers的 Authorization 中,同时也将通过 MD5 运算后的密码字符串,生成key为response,一并添加到Authorization 中。至此请求的request headers的Authorization 包含有以下信息。
    //request header Authorization: Digest username=”my name”,realm=”DIGEST”,nounce=”xxxxxxxxxxx”,algorithm=”MD5”,response=”xxxxxxxxxxxxx”
    而后发送给服务器,浏览器验证经过,返回200状态码。
    若是验证不经过,则继续返回状态码401,提示验证失败。
    缺点: 虽然 DIGEST 认证提供了高于 BASIC 认证的安全等级, DIGEST 认证提供防止密码被窃听的保护机制,但并不存在防止用户假装的保护机制,仍达不到多数 Web 网站对高度安全等级的追求标准。

    三、SSL 客户端认证

    对于 BASIC 认证和 DIGEST 认证来讲,只要输入的用户名和密码正确,便可认证是本人的行为。但若是用户名和密码被盗,就颇有可能被第三者冒充。
    而利用 SSL客户端认证则能够避免该状况的发生。在SSL认证时,必须使用https协议。
    因为SSL中的各类加密和秘钥算法过于复杂,有兴趣的能够直接阅读SSL相关书籍,本文忽略详细过程。

    四、FormBase 认证

    基于表单认证的标准规范还没有有定论,通常会使用 Cookie 来管理。
    认证过程:
    第一步:当用户在浏览器的登陆页面,输入用户名和密码,经过http请求发送给后端。
    第二步:后端保存用户的信息到session中,并返回sessionId, 经过http添加到response headers的Set-cookie中
    //response headers Set-cookie: PHPSESSID=kq8v6iujarsgflkeq7shmai9c7
    而后浏览器成功登陆,并跳转页面。
    第三步:当用户访问我的中心或者其余页面时。http请求的request header中会自动携带cookie
    //request headers Cookie: PHPSESSID=kq8v6iujarsgflkeq7shmai9c7
    这样,服务端会认为是你本人在操做。
    可是若是攻击者经过“跨站脚本攻击(XSS)”,经过docuemnt.cookie来获取cookie,则sessionID很容易被盗。
    为减轻XSS形成的损失,能够事先在 Set-cookie内加上 httponly 属性,这样就禁止了docuemnt.cookie操做。
    Set-cookie: PHPSESSID=kq8v6iujarsgflkeq7shmai9c7, httponly

    8、跨域资源共享(CORS)

    是一种机制,它使用额外的 HTTP 头来告诉浏览器 让运行在一个 origin (domain) 上的Web应用被准许访问来自不一样源服务器上的指定的资源。当一个资源从与该资源自己所在的服务器不一样的域、协议或端口请求一个资源时,资源会发起一个跨域 HTTP 请求。

    一、简单请求(不会触发CORS预检请求)

    须要知足下列 全部条件:
    第一条: 请求方式必须为 GET | HEAD | POST
    第二条: Content-Type 的值必须属于下列之一:application/x-www-form-urlencoded | multipart/form-data | text/plain
    第三条: 在请求中,不会发送自定义的头部(如X-Modified)
    例如: 在http://foo.exmaple上要访问 http://bar.other上的资源。则
    //request headers上添加 Origin: http://foo.example
    //response headers返回 Access-Control-Allow-Origin:
    因为在 http://foo.example 上要访问 http://bar.other,因此http://bar.other必需要告诉其…,能不能访问我。
    号表示该资源能够被任意外域访问。
    若是返回
    Access-Control-Allow-Origin: http://foo.example
    表示,http://bar.other的资源只能被http://foo.example访问,其余网站不能访问我。

    二、非“简单请求”(触发CORS预检请求)

    知足下列条件 之一:
    第一条: http请求方式为下列:PUT | DELETE | CONNECT | OPTIONS | TRACE | PATCH
    第二条: Content-Type 的值不属于下列之一: application/x-www-form-urlencoded | multipart/form-data | text/plain
    第三条: 在请求中,发送自定义的头部(如X-Modified)
    若是在 http://foo.exmaple 上要访问 http://bar.other/resources/po… 上的资源。且 request headers 中 Content-Type为application/xml,请求method为post。
    那么此请求是个“非简单请求”。首先浏览器会自动发送带有options选项的预检请求,而后发送实际请求
    //预检请求request headers OPTIONS /resources/post-here/ HTTP/1.1(自动,不须要设置) Access-Control-Request-Method: POST Access-Control-Request-Headers: Content-Type
    //预检请求返回response headers Access-Control-Allow-Origin: Access-Control-Allow-Methods: POST, GET, OPTIONS Access-Control-Allow-Headers: X-PINGOTHER, Content-Type Access-Control-Max-Age: 86400
    Access-Control-Allow-Origin 代表服务器容许任何其余服务器访问本身。
    Access-Control-Allow-Methods 代表服务器容许客户端使用 POST, GET, OPTIONS 方法发起请求。
    Access-Control-Allow-Headers 代表服务器容许请求中携带字段 X-PINGOTHER, Content-Type。
    Access-Control-Max-Age 代表在86400内,不会再发送预检请求。
    而后浏览器接着发送实际请求
    POST /resources/post-here/ HTTP/1.1 Content-Type: application/xml; charset=UTF-8
    实际请求返回
    HTTP/1.1 200 OK Access-Control-Allow-Origin:

    三、附带身份凭证的请求

    通常而言,对于跨域 XMLHttpRequest 或 Fetch 请求,浏览器不会发送身份凭证信息。若是要发送凭证信息,须要设置 XMLHttpRequest 的某个特殊标志位。
    var xhr = new XMLHttpRequest(); var url = ‘http://xxxxxxxxx‘; xhr.open(‘GET’, url, true); xhr.withCredentials = true; // 设置发送人请求时 携带 cookie凭证 xhr.send();
    请求发送
    GET /resources/access-control-with-credentials/ HTTP/1.1 Cookie: pageAccess=2
    请求返回
    HTTP/1.1 200 OK Access-Control-Allow-Origin: http://foo.example //在携带凭证的请求中,返回不得设置为*, 必须设置为具体域名 Access-Control-Allow-Credentials: true //必须携带这个,不然响应内容不会返回给请求的发起者

    四、CORS几个response header解释

    4.1 Access-Control-Allow-Origin
    它的值只有两种,要么, 好么具体的域名
    4.2 Access-Control-Expose-Headers
    在跨域访问时,XMLHttpRequest对象的getResponseHeader()方法只能拿到一些最基本的响应头:
    Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma
    没法访问其余的响应头(甚至在控制台network中看不到),如 set-cookie等,若是要访问其余头,则须要服务器设置,将能返回的响应头放入白名单
    Access-Control-Expose-Headers: set-cookie
    这样浏览器就可以经过getResponseHeader访问set-cookie响应头了
    4.3 Access-Control-Max-Age
    指定了预检请求的结果可以被缓存多久,在此时间内,不会再发起预检请求。
    Access-Control-Max-Age:
    *4.4 Access-Control-Allow-Credentials
    指定了当浏览器的credentials设置为true时,是否容许浏览器读取response的内容。