在我们的项目中,我们有一大堆小的css / js文件,因此当我们构建视图时,我们发现自己编写了许多<link>
或<script>
标记,迫使浏览器发出许多请求我们的css / js内容。为了解决这个问题,我们开始寻找一种方法让服务器支持所有将一个css文件或与该操作相关的每个js文件转储到响应中的请求。
在没有详细介绍的情况下,我们创建了一个Helper类,它接受文件,连接它们,并呈现如下标记:
<script type="text/javascript" src="/content/js15628453.rails"></script>
然后,ContentController有一个默认操作,它使用'js15628453'来查找Helper存储连接文件的位置并将其流出。这非常有效。
但是,正如Firebug报告的那样,浏览器总是向“/content/js15628453.rails”发送请求以获取连接文件,尽管URL始终相同且响应始终相同。我已尝试过HTTP Cache-Control
,Expires
,Last-Modified
等所有类型的组合,但尚未获得Firebug报告为从缓存中加载的内容。
为什么浏览器会忽略这些标头?我可以尝试强制缓存它吗?
答案 0 :(得分: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 :(得分:1)
@Tinister: 那么你实际上做的是处理有条件的GET 也就是说 - 当Get请求确实从客户端发送到服务器时,询问“你有没有比X更新的东西”,如果没有,服务器会说304。 你确实避免了服务器生成js和js内容的流量,但是请求的成本(即从浏览器向服务器发送http请求)仍然存在。 这些东西由Last-Modified / IfMOdifiedThen标题处理(一个用于响应,一个用于请求)和/或ETAG标题。
缓存是另一回事 - 当浏览器决定不发出GET请求时。它由“Expires”标头或Cache-control标头管理。
您可能在某处设置了Cache-Control标头,这会使客户端忽略“Expires”。 尝试设置“max-age 3600”或类似的东西,看看是否正在缓存请求(忘记FB - 而是设置断点或登录服务器以确保它没有被调用)
说过 - 在处理js / css文件时 - 你可能不会想要实际的缓存。这是因为如果浏览器决定缓存,比如一周,那么你就不能强迫它重新加载新版本。因此,如果您将新版本部署到服务器,无论新资源的新时间(oe etag)是什么,客户端都不会在本周过去之前看到它 - 因为它甚至不会发出条件GET请求
一个解决方案(如果你真的想要减轻网络安全)是设置缓存最长时间(比如一年),当资源发生变化时,你改变了URI(按原样 - 添加一个任意的查询字符串值)。这将强制浏览器重新加载新的js资源,并且永远不会再次打扰服务器,至少在下一次更新+下一个资源URI之前
答案 2 :(得分:0)
我注意到至少firefox似乎在计算时是否使用了来自初始请求的“last-modifed”标记,如果它甚至处理HEAD请求以检查“未修改”(304)响应代码。
有一个非常古老的“最后修改”时间戳似乎导致它不检查文件的任何新版本,除非明确要求。
但是,我不会非常依赖它。