如何从IIS7中删除eTag标头?


83

按照Yahoo高性能网站的最佳做法,我想从标头中删除Etags(我正在手动管理所有缓存,不需要Etags ...以及何时/如果需要扩展到服务器场,我真的希望他们走了)。我在Windows Server 2008上运行IIS7。有人知道我该怎么做吗?


它至少适用于IIS 8.0以上,如本帖子的第二个答案所示:stackoverflow.com/questions/7947420/…–
RBT

Answers:


39

在IIS7下,Etag更改号(Etag后面的部分:)始终设置为0。

因此,对于同一文件,服务器之间的Etag不再因服务器而异,因此Yahoo最佳实践不再适用。

由于您实际上无法在IIS7上取消显示ETag标头,因此最好不要完全摆弄它。到目前为止,我发现最有用的配置规则是“如果默认设置不会破坏某些内容,那就别管它了”。


2
我试图杀死etags的原因是不同的:除非我误解了一切,否则我会看到一台服务器上的IIS随意更改了etags的第一部分(即所谓的“ Filetimestamp”),尽管我的文件没有改性。例如,文件的最新版本将在浏览器中,浏览器将发送“ If-None-Match:“ 01cc3a8acccc1:0”'/'If-Modified-Since:Fri,06 Jan 2012 00:32: GMT 24”,并且IIS将以“ ETag:“ b6baeea8acccc1:0”” /“最后修改时间:2012年1月6日,星期五,GMT”响应。这些是js文件,带有foo.js?rev = xxx之类的URL,每次都传递相同的xxx。
克里斯

@Chris:我几乎做同样的事情,我允许js文件被缓存,并且只有在文件更改时才更改xxx。我不能说我曾经遇到过在任何版本的IIS上看到的行为。我怀疑您的IIS配置有点奇怪。
AnthonyWJones 2012年

谢谢。据您所知,etags的“ Filetimestamp”部分仅基于所请求文件的时间戳,而不基于机器/进程/应用程序的状态吗?
克里斯

@克里斯:据我所知,电子标签仅基于文件时间。我尝试摆弄服务器,但无法重现您看到的问题。
AnthonyWJones 2012年

我不知道使服务器不可修改是明智的策略。除了。我正在测试远期的Expires,我只是不希望HTTP 304响应-曾经。我希望事情可以长期保存,因为我知道这些资产很少更改。那里有很多IETF文档,包括HTTP规范RFC 2616,它说明了可以并且应该以站点管理员的身份进行操作,因为该人员将更加了解自己的情况。实施者一直在寻找“荒野”中发生的事情。
乔什·罗宾逊

33

您可能会认为在web.config中执行此操作可以禁用IIS7中的ETag。但是嗅探器跟踪确认ETag无论如何都是向下发送的。

<httpProtocol>
    <customHeaders>
        <remove name="ETag" />
    </customHeaders>
</httpProtocol>

使用空白也不起作用。无论如何,ETag是向下发送的。

<httpProtocol>
    <customHeaders>
        <add name="ETag" value="" />
    </customHeaders>
</httpProtocol>

如其他网站所建议的那样,将ETag设置为空白引号不起作用。

<httpProtocol>
    <customHeaders>
        <add name="ETag" value="&quot;&quot;" />
    </customHeaders>
</httpProtocol>

导致发送更多ETag:

ETag:“ 8ee1ce1acf18ca1:0”,“”

总之,至少在不编写自定义模块等的情况下,我无法尝试或想到的方法可以杀死IIS7上的ETag。


2
我尚未确认这位杰夫,但这可能是因为httpProtocol部分已锁定在网站级别。当我尝试通过web.config文件以编程方式设置iis7压缩级别时,我发现了这种情况。我最终不得不在根服务器级别解锁该部分。也许这部分有同样的问题?(我真的希望所有IIS设置都可以通过GUI获得)
Pure.Krome,2009年

1
@ Pure.Krome:在大多数情况下,结合Jeff的第二次尝试,解锁似乎对我有用...除了(当然!)图像内容。:-\ <sectionGroup name =“ system.webServer”> <section name =“ httpProtocol” overlayModeDefault =“ Allow” /> </ sectionGroup> [...] <httpProtocol> <customHeaders> <clear /> <add name = “ ETag” value =“” /> </ customHeaders> </ httpProtocol>因此,至少在这里似乎有部分解决方案。
jerhewet 2011年

@jer您应该添加一个正确的答案
Jeff Atwood

1
@jerhewet对我不起作用(Windows Server 2008 R2,IIS 7.5)
sinelaw 2013年

1
如果所有其他解决方案都无法解决,或者对我来说不可行,则可以使用一个简单的重写规则。看到我的答案:stackoverflow.com/a/18025228/705198
AndrewPK

22

我编写了一个自定义的http模块来处理此问题。确实没有听起来那么糟糕。这是代码:

using System;
using System.Web;

namespace StrongNamespace.HttpModules
{
    public class CustomHeaderModule : IHttpModule
    {
        public void Init(HttpApplication application)
        {
            application.PostReleaseRequestState += new EventHandler(application_PostReleaseRequestState);

        }

        public void Dispose()
        {
        }

        void application_PostReleaseRequestState(object sender, EventArgs e)
        {
            HttpContext.Current.Response.Headers.Remove("Server");
            HttpContext.Current.Response.Headers.Remove("X-AspNet-Version");
            HttpContext.Current.Response.Headers.Remove("ETag");
        }
    }
}

这是您想要的web.config更改:

<configuration>
    <system.webServer>
        <httpProtocol>
            <customHeaders>
                <remove name="X-Powered-By"/>
            </customHeaders>
        </httpProtocol>
        <modules>
            <add name="CustomHeaderModule" type="StrongNamespace.HttpModules.CustomHeaderModule"/>
        </modules>
    </system.webServer>
</configuration>

1
+1,但这似乎只涵盖网站要求的资源,而不是网站图标之类的东西
Brad

13

我意识到这是一个老问题,但是我在寻找解决方案时遇到了这个问题。我想我找到了一个合理的答案,并为此问题发布了答案。


确认可以正常工作,只要您在更改缓存后清除它即可;)
peter3

7

我们遇到了这个问题,甚至在IIS 7中设置空白的自定义ETag标头也不适用于所有文件(例如图像文件)。我们最终创建了一个HttpModule,该显式删除了ETag头。


6

更新:由于用户@ChrisBarr,添加了URL重写模块要求

在iis 6中很容易,您可以为'ETag'=“”添加自定义标头

在IIS 7中,阅读此线程并弄清楚如果不使用自定义http模块是不可能的,我发现您可以简单地安装Microsoft的URL Rewrite模块并添加出站重写规则,如下所示:

<outboundRules>
  <rule name="Remove ETag">
    <match serverVariable="RESPONSE_ETag" pattern=".+" />
    <action type="Rewrite" value="" />
  </rule>
</outboundRules>

这实际上有效,并且您不需要自定义的http模块(dll)。解锁system.webServer配置部分并设置customHeaders等不起作用-至少在我尝试过的所有情况下都是如此。有一个简单的出站重写规则。


1
此解决方案需要将此自定义模块安装在IIS中,对吗?
CBarr 2014年

@ChrisBarr是的-抱歉,我没有提及。答案已更新。
AndrewPK

4

顺便说一句,当您使用 iis8时 很简单

<element name="clientCache">
   <attribute name="cacheControlMode" type="enum" defaultValue="NoControl">
          <enum name="NoControl" value="0" />
          <enum name="DisableCache" value="1" />
          <enum name="UseMaxAge" value="2" />
          <enum name="UseExpires" value="3" />
  </attribute>
  <attribute name="cacheControlMaxAge" type="timeSpan" defaultValue="1.00:00:00" />
  <attribute name="httpExpires" type="string" />
  <attribute name="cacheControlCustom" type="string" />
  <attribute name="setEtag" type="bool" defaultValue="true" />
</element>

IIS 8.0:使用或不使用ETag





1

在IIS 7中,您不必再担心etags了,因为IIS配置号始终设置为0。

如果同一服务器场中有IIS6和IIS7 Web服务器,则仍然存在问题。在这种情况下,您将必须手动将IIS6配置号设置为0,如本文所述。

Etag实际上非常有用,因为您不需要像堆栈溢出那样更改文件名(即default.css?1234)。如果更改default.css文件,它将更改etag,因此后续请求将从服务器而不是从缓存获取文件。


7
远期的到期日期使ETag变得无关紧要,因为浏览器从字面上不会再请求文件,直到指定的日期(或者,当然,直到文件名更改为止)。因此,需要删除它-在这种情况下,这已经过时了。
杰夫·阿特伍德

3
@JeffAtwood并非完全正确,如果用户单击刷新按钮,浏览器将请求文件;如果etag相同,则获得304;如果diff获得200,则这里的问题是您发送了2个标头,其中1已经足够了
Sam Saffron 2012年

1

我认为这会工作..我知道删除和空白行不通。

    <configuration>
     <system.webServer>
       <httpProtocol>
          <customHeaders>
            <add name="ETag" value=" " /> 
          </customHeaders>
        </httpProtocol>
       </configuration>
     </system.webServer>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.