Appcache - 如何设置正确的缓存 headers?
Appcache - how to set right cache headers?
我创建了一个简单的清单文件,托管在页面上的 iframe 中。
问题是,清单被正确解析,但文件不是从缓存中获取的。
使用标准缓存 headers(清单和其中定义的每个文件都有私有 cache-control):
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 事件被触发并且所有文件都被提取。但是当我点击当前页面的 link 菜单时,然后在 fiddler 和浏览器开发工具中我看到,这个特定页面的文件是从服务器获取的,而不是从缓存中获取的。
然后我更改清单缓存 headers(文件 headers 与之前相同):
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
在所有浏览器上结果都是一样的。
当设置了清单的过期 header 并且我为清单中定义的文件设置了它,然后在 Firefox 上文件从 appcache 加载,但是在对每个页面的第二次请求之后。当我第一次获取页面时,不应该从缓存中加载它们吗?缓存加载到其他页面,页面由 window.location.reload 刷新并使用 swapCache。在每个页面上,清单由同一个 iframe 加载(它位于主 _Layout.cshtml)。
在Chrome情况类似于Firefox,但在这个浏览器中,第一次访问每个页面从缓存中获取图像就足够了(我没有提到我只有图像,清单中没有 js 或 css 文件)。
这一切都很好,但在 IE11 中不起作用。情况和我post开始时一样。第一次加载清单中的所有图像,但稍后当我加载任何页面时,该页面中的所有图像再次从服务器加载,而不是从缓存中加载。这是持久的。
在 IE10 中,我看到这些文件 return 带有 302 状态代码,但我没有看到它是从应用程序缓存中获取的。
使用 appcache 应该不会对服务器有任何请求。
如何让它在每个浏览器中工作?
appcache 调试和正确设置它是一个真正的疯狂。
我不想计算将它设置为当前点我损失了多少小时,我发现这不是旅程的终点。
[编辑]
也许当我将文件服务器发送到浏览器时我应该以其他方式进行? (return 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();
}
我已经在我的自定义处理程序中实现了 If-Modified-Since header 的处理,看起来它工作正常。
此外,我添加了一行代码来通过
刷新 iframe 的源代码
iframe.src = iframe.src
我创建了一个简单的清单文件,托管在页面上的 iframe 中。
问题是,清单被正确解析,但文件不是从缓存中获取的。
使用标准缓存 headers(清单和其中定义的每个文件都有私有 cache-control):
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 事件被触发并且所有文件都被提取。但是当我点击当前页面的 link 菜单时,然后在 fiddler 和浏览器开发工具中我看到,这个特定页面的文件是从服务器获取的,而不是从缓存中获取的。
然后我更改清单缓存 headers(文件 headers 与之前相同):
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
在所有浏览器上结果都是一样的。
当设置了清单的过期 header 并且我为清单中定义的文件设置了它,然后在 Firefox 上文件从 appcache 加载,但是在对每个页面的第二次请求之后。当我第一次获取页面时,不应该从缓存中加载它们吗?缓存加载到其他页面,页面由 window.location.reload 刷新并使用 swapCache。在每个页面上,清单由同一个 iframe 加载(它位于主 _Layout.cshtml)。
在Chrome情况类似于Firefox,但在这个浏览器中,第一次访问每个页面从缓存中获取图像就足够了(我没有提到我只有图像,清单中没有 js 或 css 文件)。
这一切都很好,但在 IE11 中不起作用。情况和我post开始时一样。第一次加载清单中的所有图像,但稍后当我加载任何页面时,该页面中的所有图像再次从服务器加载,而不是从缓存中加载。这是持久的。
在 IE10 中,我看到这些文件 return 带有 302 状态代码,但我没有看到它是从应用程序缓存中获取的。
使用 appcache 应该不会对服务器有任何请求。
如何让它在每个浏览器中工作?
appcache 调试和正确设置它是一个真正的疯狂。
我不想计算将它设置为当前点我损失了多少小时,我发现这不是旅程的终点。
[编辑]
也许当我将文件服务器发送到浏览器时我应该以其他方式进行? (return 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();
}
我已经在我的自定义处理程序中实现了 If-Modified-Since header 的处理,看起来它工作正常。 此外,我添加了一行代码来通过
刷新 iframe 的源代码iframe.src = iframe.src