AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 117970
In Process
Ola Herrdahl
Ola Herrdahl
Asked: 2010-03-02 09:42:24 +0800 CST2010-03-02 09:42:24 +0800 CST 2010-03-02 09:42:24 +0800 CST

IIS 7 返回 304 而不是 200

  • 772

我对 IIS 7 有一个奇怪的问题。
有时它似乎返回 304 而不是 200。

这是使用 Fiddler 捕获的示例请求:(
请注意,请求的文件尚未位于我的浏览器缓存中。)

GET https://[mysite]/Content/js/jquery.form.js HTTP/1.1
Accept: */*
Referer: https://[mysite]/Welcome/News
Accept-Language: sv-SE
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2; OfficeLiveConnector.1.4; OfficeLivePatch.1.3; .NET4.0C; .NET4.0E)
Accept-Encoding: gzip, deflate
Host: [mysite]
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: ...

请注意,请求中没有 If-Modified-Since 或 If-None-Match。
但反应仍然是:

HTTP/1.1 304 Not Modified
Cache-Control: public
Expires: Tue, 02 Mar 2010 06:26:08 GMT
Last-Modified: Mon, 22 Feb 2010 21:58:44 GMT
ETag: "1CAB40A337D4200"
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Mon, 01 Mar 2010 17:06:34 GMT

有谁知道这里可能出了什么问题?

我在 Windows Web Server 2008 R2 上运行 IIS 7。

编辑:

我找到了一种解决方法,启用缓存然后在扩展级别禁用它对我来说是诀窍。

<configuration>
  <system.webServer>
    <caching enabled="true" enableKernelCache="true">
      <profiles>
        <add extension=".png" policy="DisableCache" kernelCachePolicy="DisableCache" />
        <add extension=".gif" policy="DisableCache" kernelCachePolicy="DisableCache" />
        <add extension=".js" policy="DisableCache" kernelCachePolicy="DisableCache" />
        <add extension=".css" policy="DisableCache" kernelCachePolicy="DisableCache" />
      </profiles>
    </caching>
    <staticContent>
      <clientCache cacheControlMode="NoControl" />
    </staticContent>
  </system.webServer>
</configuration>
windows-server-2008 asp.net iis-7
  • 3 3 个回答
  • 30354 Views

3 个回答

  • Voted
  1. squillman
    2010-03-02T10:24:34+08:002010-03-02T10:24:34+08:00

    根据HTTP1.1 规范的第 14.9 节,Cache-Control 标头的no-cache指令只能由源服务器强制执行,这意味着 IIS 会忽略您请求中的标头。

    缓存控制指令可以分为以下一般类别:

      - Restrictions on what are cacheable; these may only be imposed
    

    由源服务器。

    第 14.9.1 节将public、private和定义no-cache为限制可缓存内容的指令,这些指令只能由服务器强制执行。

    如果您不希望缓存 .js 文件,则需要no-cache在应用程序中设置指令(即 ASP.NET 代码),或者您需要更改Cache-Control请求中的标头以使用该no-store指令而不是no-cache.

    编辑:
    根据您的评论 - 是的,我假设您不希望缓存文件。那么,304 可能是由于文件位于 IIS 的内部缓存之一中而出现的。看看这些:

    • 在 IIS7 中配置输出缓存
    • IIS7 中的缓存
    • 3
  2. Hobietje
    2010-06-04T20:37:59+08:002010-06-04T20:37:59+08:00

    我遇到同样的问题已经有一段时间了,并且所有缓存都关闭了……但是,我在某个时候为 IIS7 安装了压缩模块,默认情况下,它在我现有的站点上启用了静态文件的压缩。我关闭了受影响站点的所有压缩功能,现在它们似乎可以正常工作。

    • 2
  3. TheCloudlessSky
    2018-12-05T07:50:42+08:002018-12-05T07:50:42+08:00

    我们也遇到了这个错误,但我们使用的是资产管理库(Cassette)。在对此问题进行广泛调查后,我们发现此问题的根本原因在于 ASP.NET、IIS 和 Cassette 的组合。我不确定这是否是您的问题(使用HeadersAPI 而不是CacheAPI),但模式似乎是相同的。

    错误 #1

    Cassette 将Vary: Accept-Encoding标头设置为对捆绑包的响应的一部分,因为它可以使用 gzip/deflate 对内容进行编码:

    • BundleRequestHandler:https ://github.com/andrewdavey/cassette/blob/a2d9870eb0dc3585ef3dd542287595bc6162a21a/src/Cassette.Aspnet/BundleRequestHandler.cs#L78
    • HttpResponseUtil:https ://github.com/andrewdavey/cassette/blob/a2d9870eb0dc3585ef3dd542287595bc6162a21a/src/Cassette.Aspnet/HttpResponseUtil.cs#L45

    但是,ASP.NET 输出缓存将始终返回首先缓存的响应。例如,如果第一个请求有Accept-Encoding: gzip并且 Cassette 返回 gzip 压缩的内容,则 ASP.NET 输出缓存会将 URL 缓存为Content-Encoding: gzip. 对相同 URL 但使用不同的可接受编码(例如 )的下一个请求Accept-Encoding: deflate将返回缓存的响应Content-Encoding: gzip。

    此错误是由 Cassette 使用HttpResponseBase.CacheAPI 设置输出缓存设置(例如Cache-Control: public)但使用HttpResponseBase.HeadersAPI 设置Vary: Accept-Encoding标头引起的。问题是 ASP.NETOutputCacheModule不知道响应头;它只能通过CacheAPI 工作。也就是说,它希望开发人员使用不可见的紧密耦合 API,而不仅仅是标准 HTTP。

    错误 #2

    使用 IIS 7.5 (Windows Server 2008 R2) 时,错误 #1 可能会导致 IIS 内核和用户缓存出现单独的问题。例如,一旦使用 成功缓存了一个包Content-Encoding: gzip,就可以在 IIS 内核缓存中使用netsh http show cachestate. 它显示带有 200 状态代码和“gzip”内容编码的响应。如果下一个请求具有不同的可接受编码(例如 Accept-Encoding: deflate)和与捆绑包哈希匹配的If-None-Match标头,则进入 IIS 内核和用户模式缓存的请求将被视为未命中。因此,导致请求由返回 304 的 Cassette 处理:

    • BundleRequestHandler:https ://github.com/andrewdavey/cassette/blob/a2d9870eb0dc3585ef3dd542287595bc6162a21a/src/Cassette.Aspnet/BundleRequestHandler.cs#L44

    但是,一旦 IIS 的内核和用户模式处理了响应,他们将看到 URL 的响应发生了变化,并且应该更新缓存。如果netsh http show cachestate再次检查 IIS 内核缓存,缓存的 200 响应将替换为 304 响应。对捆绑包的所有后续请求,无论是否Accept-Encoding将If-None-Match返回 304 响应。我们看到了这个 bug 的破坏性影响,所有用户都被我们的核心脚本提供了 304,因为随机请求有一个意外的Accept-Encoding和If-None-Match.

    问题似乎是 IIS 内核和用户模式缓存无法根据Accept-Encoding标头而变化。作为这一点的证据,通过将CacheAPI 与下面的解决方法一起使用,似乎总是会跳过 IIS 内核和用户模式缓存(仅使用 ASP.NET 输出缓存)。这可以通过netsh http show cachestate使用下面的解决方法检查是否为空来确认。ASP.NET 直接与 IIS 工作线程通信,以根据请求选择性地启用或禁用 IIS 内核和用户模式缓存。

    我们无法在较新版本的 IIS(例如 IIS Express 10)上重现此错误。但是,错误 #1 仍然是可重现的。

    我们对这个错误的最初修复是只对其他提到的 Cassette 请求禁用 IIS 内核/用户模式缓存。通过这样做,我们在我们的 Web 服务器前部署额外的缓存层时发现了错误 #1。查询字符串 hack 起作用的原因是,如果OutputCacheModuleAPI未Cache用于根据QueryString QueryString.

    解决方法

    无论如何,我们一直在计划离开 Cassette,因此我们没有维护我们自己的 Cassette 分支(或尝试合并 PR),而是选择使用 HTTP 模块来解决这个问题。

    public class FixCassetteContentEncodingOutputCacheBugModule : IHttpModule
    {
        public void Init(HttpApplication context)
        {
            context.PostRequestHandlerExecute += Context_PostRequestHandlerExecute;
        }
    
        private void Context_PostRequestHandlerExecute(object sender, EventArgs e)
        {
            var httpContext = HttpContext.Current;
    
            if (httpContext == null)
            {
                return;
            }
    
            var request = httpContext.Request;
            var response = httpContext.Response;
    
            if (request.HttpMethod != "GET")
            {
                return;
            }
    
            var path = request.Path;
    
            if (!path.StartsWith("/cassette.axd", StringComparison.InvariantCultureIgnoreCase))
            {
                return;
            }
    
            if (response.Headers["Vary"] == "Accept-Encoding")
            {
                httpContext.Response.Cache.VaryByHeaders.SetHeaders(new[] { "Accept-Encoding" });
            }
        }
    
        public void Dispose()
        {
    
        }
    }
    

    我希望这对某人有帮助?!

    • 1

相关问题

  • 什么可能导致 IIS7 拒绝绑定到不允许导出私钥的证书?

  • 从 2003 年迁移到 2008 年 Microsoft 群集技术

  • 有什么理由使用 Windows Server 2003 而不是 Server 2008?

  • 是否可以在单个 W2008 服务器上安装 Exchange Server?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    从 IP 地址解析主机名

    • 8 个回答
  • Marko Smith

    如何按大小对 du -h 输出进行排序

    • 30 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    MikeN 在 Nginx 中,如何在维护子域的同时将所有 http 请求重写为 https? 2009-09-22 06:04:43 +0800 CST
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    0x89 bash中的双方括号和单方括号有什么区别? 2009-08-10 13:11:51 +0800 CST
  • Martin Hope
    Kyle Brandt IPv4 子网如何工作? 2009-08-05 06:05:31 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve