Appcache - 如何设置正确的缓存标头?

时间:2015-03-06 12:38:27

标签: internet-explorer-11 html5-appcache

我创建了一个简单的清单文件,该文件在页面上的iframe中托管。

这个问题是,清单被正确解析,但文件不是从缓存中获取的。

使用标准缓存标头(清单和每个文件中定义的私有缓存控件):

HTTP/1.1 200 OK
Cache-Control: private
Content-Type: text/cache-manifest; charset=utf-8
Content-Encoding: gzip
Vary: Accept-Encoding
Server: Microsoft-IIS/8.5
X-AspNetMvc-Version: 5.2
X-AspNet-Version: 4.0.30319
X-UA-Compatible: IE=Edge
Date: Fri, 06 Mar 2015 10:47:28 GMT
Content-Length: 1398

首次访问IE11 / Chrome / Firefox中的页面时,将触发appcache事件并获取所有文件。但是,当我点击菜单中的当前页面的链接时,然后在fiddler和浏览器开发工具中我看到,这个特定页面的文件是从服务器获取的,而不是从缓存中提取的。

然后我更改了清单缓存标头(对于文件标头与以前相同):

HTTP/1.1 200 OK
Cache-Control: private, max-age=0
Content-Type: text/cache-manifest; charset=utf-8
Content-Encoding: gzip
Expires: Fri, 06 Mar 2015 11:00:52 GMT
Vary: Accept-Encoding
Server: Microsoft-IIS/8.5
X-AspNetMvc-Version: 5.2
X-AspNet-Version: 4.0.30319
X-UA-Compatible: IE=Edge
Date: Fri, 06 Mar 2015 11:00:51 GMT
Content-Length: 1398

在所有浏览器上结果都一样。

当设置清单的expires头并且我为manifest中定义的文件设置它时,则在Firefox文件从appcache加载,但是在第二次请求到每个页面之后。当我第一次拿到页面时,它们不应该从缓存中加载吗?缓存已加载到其他页面上,页面由window.location.reload刷新,并使用了swapCache。在每个页面上,清单由同一个iframe加载(它位于主_Layout.cshtml上)。

在Chrome中情况类似于Firefox,但是在这个浏览器中,它应该首次到达每个页面以从缓存中获取图像(我没有提到我只有图像,而不是js或css清单中的文件。)

这一切都很好,但在IE11中它并不起作用。情况与我的帖子开头的情况相同。第一次加载清单中的所有图像,但是稍后当我加载任何页面时,此页面中的所有图像都会再次从服务器加载,而不是从缓存加载。这是持久的。

在IE10中,我看到这些文件是以302状态代码返回的,但我没有看到它是从appcache中获取的。

使用appcache不应该向服务器发出任何请求。

如何在每个浏览器中使用它?

appcache调试并正确设置它是一种真正的疯狂。

我不想计算我失去了多少小时来设置当前这一点,我发现这不是旅程的结束。

[编辑]

也许当我将文件服务器浏览器时,我应该以其他方式进行操作? (返回304或其他东西......)

这是我的http处理程序(我在ASP.NET MVC中这样做,但它不应该成为问题):

public void ProcessRequest(HttpContext context)
    {
        var current = context.Request.CurrentExecutionFilePath;

        string extension = Path.GetExtension(current).ToLower();
        if (extension == ".json")
        {
            context.Response.ContentType = "application/json";
        }
        else if (extension == ".png")
        {
            context.Response.ContentType = "image/png";
        }
        else
        {
            throw new InvalidOperationException("Unsupported file type");
        }

        context.Response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(30));

        var cache = context.Response.Cache;
        cache.SetMaxAge(new TimeSpan(0, 30, 0));


        var serverPath = context.Server.MapPath(current);
        byte[] image = File.ReadAllBytes(serverPath);

        context.Response.BinaryWrite(image);
        //context.Response.End();
    }

1 个答案:

答案 0 :(得分:0)

我已经在我的自定义处理程序处理中实现了If-Modified-Since标头,看起来它正常工作。 另外,我添加了一行代码来刷新iframe的源代码

iframe.src = iframe.src