导航:首页 > 配服务器 > 服务器如何生成etag

服务器如何生成etag

发布时间:2023-03-19 02:23:08

1. 静态资源常用的一种缓存方式

http缓存分为强缓存和协商缓存。
强缓存并不会请求服务器,同时响应码会返回200。比如使用的配置cache-control:max-age=1200

在项目中缓存图片等静态资源常用的是协商缓存。
在第一次请求静态资源首握的时候,服务器会根据资源内容生成etag, 在响应头里返回给浏览器,在下次请求的时候浏览器会在头部配置If-None-Match,携带etag来向服务器询问资源是否发生改变。若是没有发生改变会返回304,这样浏览器就不会从服务器重新获取资源而是直接使用本地缓存。采用etag可以解决文件名没有发生变化但是文件内容被修改的问题。

通常者谨庆会跟cache-control: no-cache 在一起配合使晌孙用。no-cache是指浏览器可以缓存响应,但是必须要向原始服务器提交验证请求。

参考:
https://www.imperva.com/learn/performance/cache-control/
https://blog.csdn.net/aimeimeiTS/article/details/105731709
https://www.zoo.team/article/http-cache
https://imweb.io/topic/5795dcb6fb312541492eda8c
https://aotu.io/notes/2016/09/22/http-caching/index.html

2. 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主要在断点下载时比较有用。

基本介绍

概念,性能,优势,请求流程,作用,Apache,

概念

Etag 是URL的Entity Tag,用于标示URL对象是否改变,区分不同语言和Session等等。具体内部含义是使服务器控制的,就像Cookie那样。

性能

聪明的服务器开发者会把ETags和GET请求的“If-None-Match”头一起使用,这样可利用客户端(例如浏览器)的快取。因为服务器首先产生ETag,服务器可在稍后使用它来判断页面是否已经被修改。本质上,客户端通过将该记号传回服务器要求服务器验证其(客户端)快取。 其过程如下: 客户端请求一个页面(A)。 服务器返回页面A,并在给A加上一个ETag。 客户端展现慎毕该页面,并将页面连同ETag一起快取。 客户再次请求页面A,并将上次请求时服务器返回的ETag一起传递给服务器。 服务器检查该ETag,并判断出该页面自上次客户端请求之后还未被修改,直接返回响应304(未修改——Not Modified)和一个空的回响体。

优势

1、有些URL是多语言的网页,相同的URL会返回不同的东东。还有不同的Session有不同的Cookie也就有不同的内容。这种情况下如果过 Proxy,Proxy就无法区分导致串门,只能简单的取消cache功能。Etag解决了这个问题,因为它能区分相同URL不同的对象。 2、老的HTTP标准里有个Last-Modified+If-Modified-Since表明URL对象是否改变。Etag也具有这种功能,因为对象改变也造成Etag改变,并且它的控制更加准确。Etag有两种用法 If-Match/If-None-Match,就是如果服务器的对象和客户端的对象ID(不)匹配才执行。这里的If-Match/If-None- Match都能一次提交多个Etag。If-Match可以在Etag未改变时断线重传。If-None-Match可以刷新对象(在有新的Etag时返回)。 3、Etag中有种Weak Tag,值为 W/"xxxxx"。他声明Tag是弱匹配的,只能做模糊匹配,在差异达到一定阈值时才起作用。 4、Etag对于cache CGI页面很有用。特别是论坛,论坛有办法为每个帖子页面生成唯一的Etag,在帖子未改变时,查看话题属性比较Etag就能避免刷新帖子,减少CGI操作和网路传输。比如论坛中看帖就返回Etag,减少论坛负担。 5、Etag在不同URL之间没有可比性,也烂森就是不同URL相同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 主要为了解决 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需要放在""内。

Apache

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。

3. 浏览器缓存和服务器缓存

一、浏览器缓存 浏览器缓存即http缓存;浏览器缓存根据是否需要向服务器重新发起HTTP请求将缓存过程分为两个部分,分别是 强制缓存 和 协商缓存  。浏览器第一次请求资源的时候服务器会告诉客户端是否应该缓存资源,根据响应报文中HTTP头的缓存标识,决定是否缓存结果,是则将请求结果和缓存标识存入浏览器缓存中。如下图:1.强制缓存 :浏览器会对缓存进行查找,并根据一定的规则确定是否使用缓存。 强制缓存的缓存规则? HTTP/1.0 Expires 这个字段是绝对时间,比如2018年6月30日12:30,然后在这个时间点之前的请求都会使用浏览器缓存,除非清除了缓存。 这个字段的缺点就是只会同步客户端的时间,这就有可能修改客户端时间导致缓存失效。 HTTP/1.1 cache-Control       这个是1.1的时候替换Expires的,它会有几种取值: public :所有内容都将被缓存(客户端和代理服务器都可缓存) private :所有内容只有客户端可以缓存, Cache-Control的默认取值 no-cache :客户端缓存内容,但是是否使用缓存则需要经过协商缓存来验证决定 no-store :所有内容都不会被缓存,即不使用强制缓存,也不使用协商缓存 max-age=xxx (xxx is numeric) :缓存内容将在xxx秒后失效 比如max-age=500,则在500秒内再次请求会直接只用缓存。 优先性:cache-Control > Expires 如果同时存在,cache-Control会覆盖Expires。 这个字段的缺点就是: 如果资源更新的速度是秒以下单位,那么该缓存是不能被使用的,因为它的时间单位最低是秒。 如果文件是通过服务器动态生成的,那么该方法的更新时间永远是生成的时间,尽管文件可能没有变化,所以起不到缓存的作用。上图中浏览器缓存中存在该资源的缓存结果,并且没有失效,就会直接使用缓存的内容。上图中浏览器缓存中没有该资源的缓存结果和标识,就会直接向服务器发起HTTP请求。2.协商缓存: 浏览器的强制缓存失效后(时间过期),浏览器携带缓存标识请求服务器,由服务器决定是否使用缓存。 服务器决定的规则? 控制协商缓存的字段有 Last-Modified / If-Modified-Since 和 Etag / If-None-Match。 ①Last-Modified 是服务器返回给浏览器的本资源的最后修改时间。 当下次再次请求的时候,浏览器会在请求头中带 If-Modified-Since ,即上次请求下来的 Last-Modified 的值, 然后服务器会用这个值和该资源最后修改的时间比较,如果最后修改时间大于这个值,则会重新请求该资源,返回状态码200。 如果这个值和最后修改时间相等,则会返回304,告诉浏览器继续使用缓存。 ② Etag 是服务器返回的一个hash值。 当下次再次请求的时候,浏览器会在请求头中带 If-None-Match ,即上次请求下来的 Etag 值, 然后服务器会用这个值和该资源在服务器的 Etag 值比较,如果一致则会返回304,继续使用缓存;如果不一致,则会重新请求,返回200。二、服务器缓存 上面是一个简单的流程图: 用户1访问A页面,服务器解析A页面返回给用户1,同时在服务器内存上做一定映射,把A页面缓存在硬盘上面 用户2访问A页面,服务器直接根据内存上的映射找到对应的页面缓存,直接返回给用户2,这样就减少了服务器对同一页面的重复解析 服务器缓存和浏览器缓存的区别: 服务器缓存是把页面缓存到服务器上的硬盘里,而浏览器缓存是把页面缓存到用户自己的电脑里Nginx服务器  Nginx是一个高性能的HTTP和反向代理服务器。具有非常多的优越性: 在连接高并发的情况下,Nginx是Apache服务器不错的替代品,Nginx在美国是做虚拟主机生意的老板们经常选择的软件平台之一。 Nginx提供了expires、etag、if-modified-since指令来实现浏览器缓存控制。nginx -s reload#重新加载配置文件  nginx -s reopen#重新打开log文件  nginx -s stop#快速关闭nginx服务  nginx -s quit #优雅的关闭nginx服务,等待工作进程处理完所有的请求Nginx设置静态文件的缓存过期时间  location ~.*\.(js|css|html|png|jpg)$ {   expires 3d; }  expires    3d;//表示缓存3天 expires    3h;//表示缓存3小时 expires    max;//表示缓存10年 expires    -1;//表示永远过期。 如果设置为-1在js、css等静态文件在没有修改的情况下返回的是http 304,如果修改返回http 200 对于静态资源会自动添加ETag,可以通过添加etag off指令禁止生成ETag。如果是静态文件,那么Last-Modified值为文件的最后修改时间。在开发调试web的时候,经常会碰到因浏览器缓存(cache)而经常要去清空缓存或者强制刷新来测试的烦恼,提供下apache不缓存配置和nginx不缓存配置的设置。在常用的缓存设置里面有两种方式,都是使用add_header来设置:分别为Cache-Control和Pragma。 location ~ .*\.(css|js|swf|php|htm|html )$ {   add_header Cache-Control no-store;   add_header Pragma no-cache;   } nginx gzip压缩 使用 gzip 压缩可以降低网站带宽消耗,同时提升访问速度。 主要在nginx服务端将页面进行压缩,然后在浏览器端进行解压和解析, 目前大多数流行的浏览器都迟滞gzip格式的压缩,所以不用担心。 默认情况下,Nginx的gzip压缩是关闭的,同时,Nginx默认只对text/html进行压缩 gzip on; ersio #开启gzip压缩输出 gzip_http_vn 1.0 ;#默认1.1 #其中的gzip_http_version的设置,它的默认值是1.1,就是说对HTTP/1.1协议的请求才会进行gzip压缩 #如果我们使用了proxy_pass进行反向代理,那么nginx和后端的upstream server之间是用HTTP/1.0协议通信的。 gzip_vary on ; #和http头有关系,加个vary头,给代理服务器用的,有的浏览器支持压缩,有的不支持, #所以避免浪费不支持的也压缩,所以根据客户端的HTTP头来判断,是否需要压缩 gzip_comp_level 6; #设置gzip压缩等级,等级越底压缩速度越快文件压缩比越小,反之速度越慢文件压缩比越大 1-9 gzip_proxied any; #Ngnix作为反向代理的时候启用 #expample:gzip_proxied no-cache; # off – 关闭所有的代理结果数据压缩 # expired – 启用压缩,如果header中包含”Expires”头信息 # no-cache – 启用压缩,如果header中包含”Cache-Control:no-cache”头信息 # no-store – 启用压缩,如果header中包含”Cache-Control:no-store”头信息 # private – 启用压缩,如果header中包含”Cache-Control:private”头信息 # no_last_modified – 启用压缩,如果header中包含”Last_Modified”头信息 # no_etag – 启用压缩,如果header中包含“ETag”头信息 # auth – 启用压缩,如果header中包含“Authorization”头信息 # any – 无条件压缩所有结果数据 gzip_types text/html ;#压缩的文件类型 #设置需要压缩的MIME类型,非设置值不进行压缩 #param:text/html|application/x-javascript|text/css|application/xml gzip_buffers 16 8k; #设置gzip申请内存的大小,其作用是按块大小的倍数申请内存空间设置gzip申请内存的大小,其作用是按块大小的倍数申请内存空间 #设置gzip申请内存的大小,其作用是按块大小的倍数申请内存空间 # param1:int 增加的倍数 # param2:int(k) 后面单位是k # example: gzip_buffers 4 8k; # Disable gzip for certain browsers. gzip_disable “MSIE [1-6].(?!.*SV1)”; #ie6不支持gzip,需要禁用掉ie6

4. 浏览器缓存策略

浏览器缓存策略分为两种 强缓存 (本地缓存) 和 协商缓存 (弱缓存)。
浏览器在发请求前,先检查强缓存,若没有需要的内容(未命中),则发起请求判断是否需要用弱缓存。

强缓存 是不发起请求,直接使用缓存内的内容的。浏览器将 js 、 css 、 image 、 font-family 等存到内存(存小文件)或者磁盘(存大文件)中,下次用户再访问的时候就从内存中取,以便提升性能。
协商缓存 需要往后台发请求, 通过判断来决定是使用协商缓存。如果请求内容没发生变化,则请求返回304(服务器收到请求,但内容无变化),浏览器就用缓存内的内容。

如果服务器返回的响应标头中包含 Expires (时间戳),那么客户端发起请求的时间在 Expires 之前的话,就触发强缓存。

服务器在上一次响应请求时,返回一个带 Last-Modified 的响应头,值为一个时间戳,表示该资源最后一次在服务器修改的时间。当客户端再一次请求这个资源的时候, 请求头就会带上 If-Modified-Since ,值为上次服务器发来的 Last-Modified , 服务器收到后,就和该资源最后修改时间比对, 没变化就返回304, 触发协商缓存。
弊端 : 时间间隔最小为1s,如果请求的资源在1s内发生了改变,是可能会触发协商缓存的, 导致无法获取到最新的资源。

为解决间隔最小1s的问题, If-None-Match 和 Etag 就诞生了。 Etag 是由服务器世孙厅生成的, 是每个资源搜隐的唯一标识字符串, 随资源变化而改变。 判断过程和http1.0的一致,请求的时候携带 If-None-Match ,然后服务器比较这两个值,没变化就返回304, 触发协商缓存。
弊端凯销 : 占用服务器资源较多, 虽然准确度高,但是性能上不如 Last-Modified & If-Modified-Since 的方法。不过实际的影响不会很大, 基本上可以忽略不计。

即便我们没有配置缓存策略,浏览器也会采用自己的算法来缓存资源。

5. http缓存过程

注:http 缓存只能缓存 get 方式请求的资源
缓存是指 代理服务器 客户端本地磁盘 内保存的资源副本。利用缓存可减少对源服务器的访问,因此也就节省了通信流量和通信时间。
缓存服务器是代理服务器的一种,并归类在缓存代理类型中。换句话说, 当代理转发从服务器返回的响应时,代理服务器将会保存一份资源的副本
缓存服务器的优势在于利用缓存可避免多次从源服务器转发资源。因 此客户端可就近从缓存服务器上获取资源,而源服务器也不必多次处 理相同的请求了。

浏览器缓存分 强制缓存 协商缓存 ,分别使用的字段前者是Expires和Cach-control,后者是 Etag 和 Last-modified。

Expires (http/1.0):设的是资源的过期时间(绝对时间),浏览器判断这次请求的时候是不是超过这个日期,没超的话就直接读取缓存中的资源,不向服务器发请求。

Pragma :字段值为“no-cache”的时候,会通知客户端不要对该资源读缓存,即每次都得向服务器发一次请求才行。但是这种禁用缓存的形式作用不是那么太大:1. 仅有IE才能识别这段meta标签含义,其它主流浏览器仅能识别“Cache-Control: no-store”的meta标签。2. 在IE中识别到该meta标签含义,并不一定会在请求字段加上Pragma,但的确会让当前页面每次都发新请求,但是仅限页面,页面上的资源则不受影响。
如果Pragma和Expires一起出现的话,Pragma的优先级是高的。

Cach-Control (http/1.1):缓存控制 示例:

Cache-Control 有三种属性:缓冲能力、过期时间和二次验证。

缓冲能力:

过期时间:

二次验证:

Expires使用的是服务端时间,可能出现客户端和服务端时间不同步,导致本地缓存无用或无法过期。
Max-Age使用的是客户端本地时间的计算,不会出现这个问题,推荐Max-Age。
如果同时启用了Cache-Control和Pragma ,Expires,Cache-Control优先级高。

Last-Modified / If- Modified-Since (http/1.0):判断资源最后修改时间,只要这个日期改变了就不使用缓存。浏览器的头部是If- Modified-Since,服务端的是Last-Modified,如果两个匹配,代表服务器资源未改变,服务端不会返回资源实体,只返回头部,通知浏览器使用缓存。
缺点:可能有些文件会周期性地改变日期,但是内容其实没变,但是该字段只判断最后修改时间,
E-tag / If-None-Match (http/1.1):Etag 是服务器针对请求的资源文件生成的唯一标识,只要文件内容没变化,则Etag值不变,克服了 Last-Modified / If- Modified-Since 的缺点。浏览器的头部是If-None-Match,服务端的是E-tag,如果两个匹配,代表内容未改变,通知浏览器使用缓存。
Etag 缺点:不适用于分布式系统 ,因为每个服务器上的 Etag 值不同。

如果同时带有E-tag和Last-Modified,服务端优先检查E-tag。

阅读全文

与服务器如何生成etag相关的资料

热点内容
python计算子网掩码 浏览:57
加密u盘制作成iso镜像 浏览:491
oppo大文件夹图标 浏览:173
用cmd打开python文件 浏览:366
程序员磁盘知识 浏览:584
左搂右抱命令 浏览:931
法律大还是行政命令大 浏览:354
中国银行手机app在哪里刷脸 浏览:900
epidata如何编程 浏览:989
助眠解压玩具电动 浏览:235
4k显示器编程 浏览:267
什么错误在编译时会发现 浏览:700
学会自己解压英语 浏览:44
安卓豪华版是什么意思 浏览:684
c语言编程软件打开 浏览:21
碧蓝航线图片文件夹位置 浏览:671
winme编译 浏览:522
淘宝上买东西发顺丰快递地址都加密吗 浏览:415
批处理编译VS代码 浏览:891
uchar哪个编译器 浏览:28