2009-04-16 99 views
1

在我们的项目中,我们有一大堆小的css/js文件,所以当我们构建视图时,我们发现自己写了很多<link><script>标签,迫使浏览器对我们的css/js内容提出许多请求。为了解决这个问题,我们开始寻找一种服务器支持的方式,将所有请求转化为一个请求,将每个css文件或与该操作关联的每个js文件转储到响应中。强制浏览器缓存对Castle MonoRail操作的请求?

没有进入太多细节,我们创建了一个助手类,接受文件,连接起来,然后呈现一个标签,像这样:

<script type="text/javascript" src="/content/js15628453.rails"></script>

的ContentController则具有使用默认的行动“ js15628453'找到Helper存储连接文件的位置并将其流出。这工作得很好。

但是,正如Firebug报告的那样,浏览器始终会发送一个请求到“/content/js15628453.rails”以获取连接文件,尽管URL始终是相同的,并且响应始终是相同的。我尝试过所有类型的HTTP Cache-Control,Expires,Last-Modified等标题的组合,但尚未得到Firebug从缓存中加载的报告。

为什么浏览器可能忽略这些头文件?有没有其他选择我可以尝试强制它被缓存?

回答

2

那么,我想到了这一点,以便为那些可能在搜索引擎中找到这个问题的人带来好处,我会继续并回答我自己的问题。

基本上,我不得不写来设置一个304个状态自己的逻辑:

DateTime lastModified = // some date 
string ifModifiedSince = Request.Headers["If-Modified-Since"]; 
if (ifModifiedSince != null) 
{ 
    var requestDate = DateTime.Parse(ifModifiedSince); 
    if (requestDate <= lastModified) 
    { 
     CancelView(); 
     Response.StatusCode = 304; 
     return; 
    } 
} 

Response.CachePolicy.SetLastModified(lastModified); 

// Logic to write the file to the OutputStream 

我错误地以为浏览器将只使用它的缓存副本,如果它的存在,并没有过期,而它显然需要询问服务器其缓存副本是否仍然有效。

1

@Tinister: 那么实际上你做的是处理条件GET 那就是 - 当一个Get请求并从客户机到服务器,问:“你有什么比X更新”和服务器说304,如果不。 你确实避免了生成js的服务器和js内容的流量,但是请求的成本(即 - 从浏览器发送http请求到服务器)仍然存在。 这个东西正在被Last-Modified/IfMOdifiedThen Headers(一个用于响应,一个用于请求)和/或ETAG头部处理。

缓存是一个不同的事情 - 即当浏览器决定不发出GET请求时。它由“Expires”标头或Cache-control标头管理。

您可能会在某处设置Cache-Control标头,并使客户端忽略“Expires”。 尝试设置“max-age 360​​0”或类似的东西,看看请求是否被缓存(忘了关于FB - 而不是设置断点或登录服务器以确保它不被调用)

说 - 在处理js/css文件时 - 你可能不会想要实际的缓存。那是因为如果浏览器决定缓存,比如一周,那么你不能强制它重新加载一个新版本。因此,如果您将新版本部署到服务器,则无论新资源的新时间(oe etag)如何,客户端都会在一周过后才会看到它 - 因为它永远不会发出条件GET请求。一个解决方案(如果你真的想减轻网络安全性)是设置最大时间(比如一年)的缓存,当资源改变时,你改变URI(按原样 - 添加一个任意的查询字符串值)。这将迫使浏览器重新加载新的js资源,并且永远不会再次打扰服务器,至少直到下一次更新+下一个资源URI

0

我注意到至少firefox似乎利用“最后修改”当计算它是否处理HEAD请求时检查“未修改”(304)响应代码的初始请求。

有一个非常古老的“最后修改”时间戳看起来会导致它不检查该文件的任何新版本,除非明确要求。

但是,我不会严重依赖这一点。