强制浏览器缓存对 Castle MonoRail 操作的请求?

发布于 2024-07-17 08:47:42 字数 730 浏览 8 评论 0原文

在我们的项目中,我们有一大堆小的 css/js 文件,因此当我们构建视图时,我们发现自己编写了许多

无需过多讨论,我们创建了一个 Helper 类,它接受文件、连接它们并呈现一个标签,如下所示:

然后,ContentController 有一个默认操作,它使用“js15628453”来查找 Helper 存储串联文件的位置并将其流式传输。 这确实有效。

然而,正如 Firebug 报告的那样,浏览器总是向“/content/js15628453.rails”发送请求以获取串联文件,尽管 URL 始终相同且响应始终相同。 我已经尝试了 HTTP Cache-ControlExpiresLast-Modified 等标头的所有类型的组合,但尚未获得Firebug 报告从缓存加载的内容。

为什么浏览器可能会忽略这些标头? 我还可以尝试强制缓存其他选项吗?

In our project, we have a whole bunch of small css/js files, so when we build views we find ourselves writing many <link> or <script> tags, forcing the browser to make many requests for our css/js content. To remedy this, we started looking for a way for server to shore that all up into one request that dumps every css file or every js file associated with the action into the response.

Without going into too much detail, we created a Helper class that accepts the files, concatenates them, and renders a tag like so:

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

The ContentController then has a default action which uses 'js15628453' to find where the Helper stored the concatenated file and streams it out. This works really well.

However, as Firebug reports it, the browser always sends a request to "/content/js15628453.rails" to get the concatenated file, despite the fact that the URL is always the same and the response is always the same. I've tried all types of combinations of the HTTP Cache-Control, Expires, Last-Modified, etc headers, but have yet to get something that Firebug reports as loaded from the cache.

Why might the browser be ignoring those headers? Are there any other options I can try to force it to be cached?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

二智少女猫性小仙女 2024-07-24 08:47:42

好吧,我想通了,所以为了那些可能在搜索引擎中找到这个的人的利益,我将继续回答我自己的问题。

基本上,我必须自己编写逻辑来设置 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

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

Well, I figured this out so for the benefit of those who may find this in a search engine I'll go ahead and give an answer to my own question.

Basically, I had to write the logic to set a 304 status myself:

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

I had incorrectly assumed the browser would just use its cached copy if it existed and hadn't expired, whereas it apparently needs to ask the server if its cached copy is still valid.

一袭水袖舞倾城 2024-07-24 08:47:42

@蒂尼斯特:
实际上你所做的是处理条件 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 之前

@Tinister:
Well actually what you do is to deal with Conditional GET
That is - when a Get request does go from client to server, asking "do you have anything newer than X" and the server say 304 if not.
you do avoid the Server generating the js, and the traffic of the js content, however the cost of the request (that is - sending an http request from browser to server) is still there.
this stuff is being handled by the Last-Modified/IfMOdifiedThen Headers (one for responses, one for requests) and/or the ETAG header.

Caching is a different thing - that is when the browser decides not to issue the GET request at all. it is being managed by the "Expires" header or the Cache-control header.

you might have a Cache-Control header being setup somewhere and it makes the client disregard the "Expires".
Try setting "max-age 3600" or something like it, and see if the request is being cached (forget about FB - instead setup a breakpoint or logging on the server to be sure that it's not being called)

having said that - when dealing with js/css files - you might not want actual caching. that is because if the browser does decide to cache, say for a week, then you cannot force it to reload a new version. so if you deploy a new version to the server, the client won't see it until the week has passed, no matter what the new time (oe etag) of the new resource is - cuz it will never even issue the conditional GET request.

One solution (if you really want to relieve network preassure) is to setup caching for maximum time (say a year), and when the resource changes, you change the URI (as is - add an arbitrary querystring value). this will force the browser to reload the new js resource, and never bother the server again, at least until the next update + next resource URI

各自安好 2024-07-24 08:47:42

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

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

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

I have noticed that atleast firefox seems to utilize "last-modifed" stamp from the initial request when calculating if it even processes a HEAD-request to check for "not-modified" (304) response-code.

Having a really old "last-modified" timestamp seem to cause it to not check for any new versions of the file unless explicitly asked for.

However, I wouldn't heavily rely on that.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文