当前位置: 首页 > 编程日记 > 正文

HTTP协议Etag详解

HTTP协议规格说明定义ETag为“被请求变量的实体值”。

另一种说法是,ETag是一个可以与Web资源关联的记号(token)。典型的Web资源可以一个Web页,但也可能是JSON或XML文档。服务器单独负责判断记号是什么及其含义,并在HTTP响应头中将其传送到客户端,以下是服务器端返回的格式:

ETag:"50b1c1d4f775c61:df3"

客户端的查询更新格式是这样的:

If-None-Match : W / "50b1c1d4f775c61:df3"

如果ETag没改变,则返回状态304然后不返回,这也和Last-Modified一样。

测试Etag主要在断点下载时比较有用。

Etag - Last-Modified和Etags如何帮助提高性能?

聪明的开发者会把Last-Modified和ETags请求的http报头一起使用,这样可利用客户端(例如浏览器)的缓存。因为服务器首先产生Last-Modified/Etag标记,服务器可在稍后使用它来判断页面是否已经被修改。本质上,客户端通过将该记号传回服务器要求服务器验证其(客户端)缓存。
过程如下:
1.客户端请求一个页面(A)。
2.服务器返回页面A,并在给A加上一个Last-Modified/ETag。
3.客户端展现该页面,并将页面连同Last-Modified/ETag一起缓存。
4.客户再次请求页面A,并将上次请求时服务器返回的Last-Modified/ETag一起传递给服务器。
5.服务器检查该Last-Modified或ETag,并判断出该页面自上次客户端请求之后还未被修改,直接返回响应304和一个空的响应体。

Etag - 作用

Etag 主要为了解决 Last-Modified 无法解决的一些问题。

1、一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新GET;

2、某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改无法判断(或者说UNIX记录MTIME只能精确到秒)

3、某些服务器不能精确的得到文件的最后修改时间;

为此,HTTP/1.1 引入了 Etag(Entity Tags).Etag仅仅是一个和文件相关的标记,可以是一个版本标记,比如说v1.0.0或者说"2e681a-6-5d044840"这么一串看起来 很神秘的编码。但是HTTP/1.1标准并没有规定Etag的内容是什么或者说要怎么实现,唯一规定的是Etag需要放在""内。

Etag - 工作原理

Etag由服务器端生成,客户端通过If-Match或者说If-None-Match这个条件判断请求来验证资源是否修改。常见的是使用If-None-Match.请求一个文件的流程可能如下:

====第一次请求===
1.客户端发起 HTTP GET 请求一个文件;
2.服务器处理请求,返回文件内容和一堆Header,当然包括Etag(例如"2e681a-6-5d044840")(假设服务器支持Etag生成和已经开启了Etag).状态码200

====第二次请求===
1.客户端发起 HTTP GET 请求一个文件,注意这个时候客户端同时发送一个If-None-Match头,这个头的内容就是第一次请求时服务器返回的Etag:2e681a-6-5d044840
2.服务器判断发送过来的Etag和计算出来的Etag匹配,因此If-None-Match为False,不返回200,返回304,客户端继续使用本地缓存;

流程很简单,问题是,如果服务器又设置了Cache-Control:max-age和Expires呢,怎么办?
答案是同时使用,也就是说在完全匹配If-Modified-Since和If-None-Match即检查完修改时间和Etag之后,服务器才能返回304.(不要陷入到底使用谁的问题怪圈)

Etag - Apache中Etag实现

1.Apache首先判断是不是弱Etag,这个留在下面讲。如果不是,进入第二种情况:

强Etag根据配置文件中的配置来设置Etag值,默认的Apache的FileEtag设置为:

FileEtag INode Mtime Size

也就是根据这三个属性来生成Etag值,他们之间通过一些算法来实现,并输出成hex的格式,相邻属性之间用-分隔,比如:

Etag"2e681a-6-5d044840"

这里面的三个段,分别代表了INode,MTime,Size根据算法算出的值的Hex格式,(如果在这里看到了非Hex里面的字符(也就是0-f),那你可能看见神了:))

当然,可以改变Apache的FileEtag设置,比如设置成FileEtagSize,那么得到的Etag可能为:

Etag"6"

总之,设置了几个段,Etag值就有几个段。(不要误以为Etag就是固定的3段式)

说明
这里说的都是Apache2.2里面的Etag实现,因为HTTP/1.1并没有规定Etag必须是什么样的实现或者格式,因此,也可 以修改或者完全编写自己的算法得到Etag,比如"2e681a65d044840",客户端会记住并缓存下这个Etag(Windows里面保存在哪 里,下次访问的时候直接拿这个值去和服务器生成的Etag对比。

注意
不管怎么样的算法,在服务器端都要进行计算,计算就有开销,会带来性能损失。因此为了榨干这一点点性能,不少网站完全把Etag禁用了(比如Yahoo!),这其实不符合HTTP/1.1的规定,因为HTTP/1.1总是鼓励服务器尽可能的开启Etag。

Etag - 弱校验(弱Etag)

重新考虑前面提到的3个问题:

问题1、一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新GET;

解决办法:如果使用强Etag,每次得会要求重新GET页面,如果使用Etag,比方说设置成 File Etag Size 等,就可以忽略 MTime 造成的 Last-Modified 时间修改从而影响了 If-Modified-Since(IMS) 这个校验了。这点和弱Etag无关。

问题2、某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改无法判断(或者说UNIX记录MTIME只能精确到秒)

解决办法:如果是这种情况,Apache会自动判断请求时间和修改时间之间的差值,如果小于1s,Apache会认为这个文件在这1秒内可能会再次被修改, 因此生成一个弱Etag(WeakEtag),这个Etag仅仅基于MTime来生成,因此MTime只能精确到s,所以1s内生成的Etag总是一样, 这样就避免了使用强Etag造成的1s内频繁的刷新Cache的情况。(貌似不用Etag,仅仅使用Last-Modified就可以解决,但是这针对的 仅仅是修改超级频繁的情况,很多文件可能同时也使用强Etag验证)。弱Etag以W/开始,比如:W/"2e681a"

问题3、某些服务器不能精确的得到文件的最后修改时间;

解决办法:生成Etag,因为Etag可以综合Inode,MTime和Size,可以避免这个问题

转载于:https://www.cnblogs.com/flysnow-z/archive/2012/08/17/2644420.html

相关文章:

【第13周复盘】小朋友们也开始卷了

「青少年编程竞赛交流群」已成立(适合6至18周岁的青少年),公众号后台回复【Scratch】或【Python】,即可进入。如果加入了之前的社群不需要重复加入。 微信后台回复“资料下载”可获取以往学习的材料(视频、代码、文档&…

原生ajax+php上传图片的简单实现

前端 <input type"file" onclick"updown" accept"image/png,image/gif">//accept限制上传的类型<script> function upload1(obj){ var files obj.files ; var formData new FormData();$.ajax({url: download.php,type: "POS…

参加软件测试培训前景怎么样

软件测试在近几年的发展前景还是非常不错的&#xff0c;很多人都开始参加软件测试培训班学习技术&#xff0c;要想具体了解参加软件测试培训前景怎么样?来看看下面的详细介绍就知道了。 参加软件测试培训前景怎么样?各大招聘平台上&#xff0c;都能看到测试的影子&#xff0c…

如果你喜欢一个程序员小伙

程序员向来是善于幽默自嘲的群体&#xff0c;但从某种程度上影响了咱程序员在广大女同胞心中的印象啊&#xff5e;&#xff5e;于是写下此篇&#xff08;有从别处看到的3句加进来的&#xff09;&#xff0c; 就算是为咱程序员做个广告&#xff5e;&#xff5e;要是觉得有点过的…

遇到大容量磁盘你该怎么办?

GPT 磁盘分区&#xff1a;首先&#xff0c;你得有一块 GPT 分区的硬盘。小于 2 TB 的磁盘也可以转为 MBR 磁盘&#xff0c;但是大于 2 TB 的磁盘则需要使用 GPT 分区&#xff0c;否则大于 2 TB 的部分将被你封印。 挂载硬盘后&#xff0c;打开系统并以 root 身份登陆。这里博主…

如何解决Python3写入CSV出现‘gbk‘ codec can‘t encode的错误

今天&#xff0c;我在 Windows 上用 Python3 爬取知乎上有关中医的问答&#xff0c;但是在把爬取的内容写进CSV文件的时候&#xff0c;出现了以下异常。 UnicodeEncodeError: gbk codec cant encode character \u2630 in position 3969: illegal multibyte sequence经过上网查…

ui设计怎样做出有效果的视觉层级?

作为一名UI设计师&#xff0c;大家应该清楚的了解到每一款产品都有不同的风格和设计&#xff0c;但是每一款UI设计元素都是有通风之处的&#xff0c;如何能够做出有效的视觉层级&#xff0c;对用户的体验有着十分积极的影响。本期UI设计培训教程就为大家详细的介绍一下ui设计怎…

Java RandomAccessFile的使用

Java的RandomAccessFile提供对文件的读写功能&#xff0c;与普通的输入输出流不一样的是RamdomAccessFile可以任意的访问文件的任何地方。这就是“Random”的意义所在。 RandomAccessFile的对象包含一个记录指针&#xff0c;用于标识当前流的读写位置&#xff0c;这个位置可以向…

【组队学习】【24期】集成学习(中)

集成学习&#xff08;中&#xff09; 开源内容&#xff1a; https://github.com/datawhalechina/team-learning-data-mining/tree/master/EnsembleLearning 基本信息 贡献人员&#xff1a;李祖贤、薛传雨、赵可、杨毅远、陈琰钰、李嘉骐学习周期&#xff1a;12天学习形式&a…

Android发布项目到外部仓库

为什么80%的码农都做不了架构师&#xff1f;>>> 关于android发布仓库到外部项目的文章&#xff0c;目前大概为分两类&#xff1a; 一种是发布到bintray、jcenter上&#xff0c;一种是将项目上传到github&#xff0c;然后利用jitpack自动打包&#xff0c;下面简单说…

Java零基础学习难吗

java编程是入行互联网的小伙伴们大多数的选择&#xff0c;那么对于零基础的小伙伴来说Java零基础学习难吗?如果你是初学者&#xff0c;你可以很好的理解java编程语言。并不困难。如果你的学习能力比较高&#xff0c;那么你对Java的理解会更快。而如果你恰巧已经掌握了c或c语言…

玩转“网上邻居”之网络配置(二)

接上篇二、混合系统网络目前实际应用中单一系统的对等网络已不是主流&#xff0c;主要是由于这种网络性能较低&#xff0c;缺乏很好看安全及网络管理能力。目前在各企事业单位中普遍应用的还是基于多系统的域结构混合网络。但因目前主流应用的系统比较多&#xff0c;所以各种网…

UVa 10180 - Rope Crisis in Ropeland!

题目链接&#xff1a;http://uva.onlinejudge.org/index.php?optioncom_onlinejudge&Itemid8&category41&pageshow_problem&problem1121 题意&#xff1a;给出两点坐标&#xff0c;用一条最短的线&#xff08;曲线或者直线&#xff09;连接起来&#xff0c;坐…

【组队学习】【24期】河北邀请赛(二手车价格预测)

河北邀请赛&#xff08;二手车价格预测&#xff09; 开源内容&#xff1a; https://github.com/datawhalechina/team-learning-data-mining/tree/master/SecondHandCarPriceForecast 数据挖掘实践&#xff08;二手车价格预测&#xff09;的内容来自 Datawhale与天池联合发起…

什么样的人合适学习Python?

什么样的人合适学习Python?近几年&#xff0c;关注Python技术的小伙伴越来越多&#xff0c;很多人都想知道Python培训好不好学?难不难学?哪些人适合学?来看看下面的详细介绍。 Python培训分享&#xff1a;什么样的人合适学习Python?想学好python&#xff0c;关键还是看三点…

Table doesn't have a primary key

从数据库取出来的数据&#xff0c;一般会放在一个DataTable中。但是&#xff0c;Insus.NET想实现一个小功能&#xff0c;就是在这个DataTable能快速找到某一行记录&#xff0c;来显示于asp.net页面上。这时我们可以使用DataTable的Find()成員函式來檢查資料是否已存在。但当Ins…

【组队学习】【24期】数据挖掘实践(智慧海洋)

数据挖掘实践&#xff08;智慧海洋&#xff09; 开源内容&#xff1a; https://github.com/datawhalechina/team-learning-data-mining/tree/master/wisdomOcean 基本信息 贡献人员&#xff1a;李运佳、李万业、赵信达、张晋、刘羽中、王贺、肖明远学习周期&#xff1a;12天…

vim 输入中文

收藏一些有关vim输入中文的链接为了以后方便查看 http://vimim.googlecode.com/svn/vimim/vimim.html http://www.wang3feng.com/2010/07/03/e5-ad-a6vim-e4-ba-8c-e5-a6-82-e4-bd-95-e5-9c-a8vim-e4-b8-ad-e6-9b-b4-e5-a5-bd-e7-9a-84-e8-be-93-e5-85-a5-e4-b8-ad-e6-96-87/ 本…

Web前端工程师的一些常见误区

想要作为一名合格的web前端工程师&#xff0c;那么掌握基本的开发技术是远远不够的&#xff0c;在职场中还要少犯一些错误&#xff0c;本期小编为大家分享的web前端培训教程主要是介绍一些web前端工程师常见的误区&#xff0c;希望对大家有所帮助。 web前端培训分享&#xff1a…

WPF关闭应用程序,释放Window窗口资源方法

WindowsForm里一个Application.Exit();方法就可以关闭应用程序&#xff0c;释放掉资源。 WPF里Application类没有该方法&#xff0c;但是有一个Exit的事件驱动&#xff0c;在WPF应用程序里面关闭程序讲究很多&#xff1a; 在WPF应用程序的关闭是有ShutdownMode属性设置&#xf…

《Cisco/H3C交换机配置与管理完全手册(第2版)》终稿封面和目录

无数网友一直殷切期待和关注的《Cisco/H3C交换机配置与管理完全手册》&#xff08;第2版&#xff09;一书即将于本月底正式上市了。到时对于真实读者&#xff0c;写书评后可以参加全额返款的抽奖活动&#xff0c;加入我的微博(本博客首页中有)&#xff0c;留意我发布的最新资讯…

【组队学习】【24期】Docker教程

Docker教程 开源内容&#xff1a; https://github.com/datawhalechina/team-learning-program/tree/master/Docker 基本信息 贡献人员&#xff1a;苏鹏、陈安东&#xff0c;于鸿飞&#xff0c;陈长沙&#xff0c;丁一超&#xff0c;乔石&#xff0c;刘雯静学习周期&#xf…

网站ui的配色有哪些需要注意的?

作为一名UI设计师&#xff0c;那么关于配色的问题是非常注重的&#xff0c;尤其是做一款网站设计&#xff0c;配色方面要非常注意&#xff0c;本期小编为大家介绍的UI设计培训教程就是关于网站ui的配色有哪些需要注意的?来看看下面的详细介绍。 UI设计培训分享&#xff1a;网站…

2、安装Lync Server 2013

一、实验环境拓扑的准备工作 二、开始安装Lync Server 2013 安装Lync Server系统主要包含以下的内容&#xff1a;安装本地配置存储、安装Lync Server 组件、请求并分配Lync证书、启动服务。 运行Lync Server 2013的安装程序&#xff0c;选择“安装或更新Lync Server系统”&…

!! 机器学习常用工具

http://fuliang.iteye.com/blog/955023 机器学习 Support Vector Machine SVMlightAn implementation of Vapniks Support Vector Machine LIBSVMA Library for Support Vector Machines Decision Tree C4.5The "classic" decision-tree tool, developed by J. R. Qu…

Datawhale组队学习周报(第010周)

本周&#xff08;04月19日~04月25日&#xff09;&#xff0c;第 24 期组队学习正在如火如荼的进行中。本期组队学习&#xff0c;一共有 5 门开源课程&#xff0c;共组建了 6 个学习群&#xff0c;参与的学习者有 788 人。另外&#xff0c;第 25 期组队学习也蓄势待发准备与大家…

零基础怎么学习Java?

最近几年&#xff0c;有很多小伙伴都比较关注“零基础怎么学习Java?”这个问题&#xff0c;因为很多小伙伴都是从其他行业转型来参加java培训学习的&#xff0c;都很担心自己学不会&#xff0c;那么来看看下面的详细介绍吧。 零基础怎么学习Java?来看看以下才几点java培训学习…

如何爬取知乎中问题的回答以及评论的数据?

如何爬取知乎中问题的回答以及评论的数据&#xff1f; 我们以爬取“为什么中医没有得到外界认可&#xff1f;”为例来讨论一下如何爬取知乎中问题的回答以及评论的数据。 爬取网页数据通常情况下会经历以下三个步骤。 第一步&#xff1a;网页分析&#xff0c;确认自己所要数据…

Facebook如何使用Avartarnode提升HDFS可靠性

在不久前的Hadoop峰会上&#xff0c;Facebook的工程师Andrew Ryan分享了他们如何使用Namenode和Avatarnode提升HDFS可靠性的方法。Ryan从2009年开始&#xff0c;就参与到了Facebook的 Hadoop开发中。在他的帮助下&#xff0c;Facebook的Hadoop和HDFS数据基础设施&#xff0c;从…

无法远程分发安装软件原因

一、问题及原因 最近做实验在域环境通过组策略分发软件、防病毒网络版远程安装客户端软件都失败&#xff0c;真的原因在于&#xff1a;阻止对Windows注册表的远程访问引起来的。客户端是XP系统&#xff0c;通过Ghost版本安装的&#xff0c;默认是禁用Windows XP注册表的远程访…