1

在我们的项目中,我们有一大堆小的 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-ControlExpiresLast-Modified等标头组合,但还没有得到 Firebug 报告的从缓存中加载的内容。

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

4

3 回答 3

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

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

于 2009-04-16T22:35:32.363 回答
1

@Tinister:实际上,您要做的是处理条件GET,即-当Get请求确实从客户端发送到服务器时,询问“您是否有比X更新的东西”,如果没有,服务器会说304。您确实避免了服务器生成 js 和 js 内容的流量,但是请求的成本(即 - 从浏览器向服务器发送 http 请求)仍然存在。这些东西由 Last-Modified/IfMOdifiedThen 标头(一个用于响应,一个用于请求)和/或 ETAG 标头处理。

缓存是另一回事——即当浏览器决定根本不发出 GET 请求时。它由“Expires”标头或 Cache-control 标头管理。

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

话虽如此 - 在处理 js/css 文件时 - 您可能不需要实际的缓存。那是因为如果浏览器确实决定缓存,比如说一个星期,那么你不能强迫它重新加载一个新版本。因此,如果您将新版本部署到服务器,客户端将在一周过去之前看到它,无论新资源的新时间(oe etag)是什么 - 因为它甚至不会发出条件 GET 请求.

一种解决方案(如果您真的想减轻网络压力)是设置缓存的最长时间(比如一年),并且当资源更改时,您更改 URI(按原样 - 添加任意查询字符串值)。这将强制浏览器重新加载新的 js 资源,并且不再打扰服务器,至少在下一次更新 + 下一个资源 URI 之前

于 2009-04-18T20:33:46.977 回答
0

我注意到,至少 firefox 在计算它是否甚至处理 HEAD 请求以检查“未修改”(304)响应代码时似乎使用了初始请求中的“最后修改”标记。

拥有一个非常旧的“最后修改”时间戳似乎会导致它不检查文件的任何新版本,除非明确要求。

但是,我不会严重依赖它。

于 2009-05-13T21:46:26.830 回答