如何使用 Compojure 生成修改后的 http 标头?

发布于 2024-11-09 20:25:58 字数 774 浏览 0 评论 0原文

我正在尝试提高客户端从我的 Compojure 网络服务器获取页面的性能。我们使用 (compojure.route/resources "/") 提供一堆静态文件(JS、CSS),它在文件系统上查找文件,将它们转换为 URL,然后将它们提供给响如溪流。通过转换为流,似乎会丢失所有文件元数据,例如 mod 时间。

我可以包装静态资源处理程序并添加 ExpiresCache-Control: max-age 标头,但这会阻止客户端发送任何请求。很有用,但这些文件有时会发生变化(当我们发布版本时)。

理想情况下,我希望客户端信任自己的缓存版本,例如一个小时,并在该小时过去后使用 If-Modified-Since 标头发出请求。然后我们可以返回304 Not Modified,客户端就可以避免下载数百公斤的 JavaScript。

看起来我可以在提供响应时设置 Last-Modified 标头,这会导致客户端使用 If-Modified-Since 标头来限定后续请求。太棒了,除了我必须重写 compojure.route/resources 中的大部分代码才能添加 Last-Modified - 不难,但乏味 - 并发明一些更多代码来识别和响应 If-Modified-Since 标头。这不是一项艰巨的任务,但也不是一项简单的任务。

这已经存在于某处吗?我找不到它,但这似乎是一个足够常见、足够大的任务,以至于现在有人已经为它编写了一个库。

I'm trying to improve performance for clients fetching pages from my Compojure webserver. We serve up a bunch of static files (JS, CSS) using (compojure.route/resources "/"), which looks for files on the filesystem, converts them to URLs, and then serves them to Ring as streams. By converting to streams, it seems to lose all file metadata, such as the mod time.

I can wrap the static-resource handler and add an Expires or Cache-Control: max-age header, but that prevents the client from sending any request at all. Useful, but these files do change on occasion (when we put out a release).

Ideally I'd like the client to trust its own cached version for, say, an hour, and make a request with an If-Modified-Since header after that hour has passed. Then we can just return 304 Not Modified and the client avoids downloading a couple hundred kilos of javascript.

It looks like I can set a Last-Modified header when serving a response, and that causes the client to qualify subsequent requests with If-Modified-Since headers. Great, except I'd have to rewrite most of the code in compojure.route/resources in order to add Last-Modified - not difficult, but tedious - and invent some more code to recognize and respond to the If-Modified-Since header. Not a monumental task, but not a simple one either.

Does this already exist somewhere? I couldn't find it, but it seems like a common enough, and large enough, task that someone would have written a library for it by now.

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

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

发布评论

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

评论(2

胡渣熟男 2024-11-16 20:25:58

FWIW,我通过使用Ring的wrap-file-info中间件来实现这个工作;我有点尴尬,因为我在 Compojure 而不是 Ring 中寻找了这个。然而,compojure.routefilesresources 处理程序都提供流而不是文件或 URL,当然 Ring 无法计算从中取出元数据。

我基本上必须编写一个 resources 的副本,它返回一个 File ;当包裹在满足我需求的 wrap-file-info 中时。仍然不介意一个稍微好一点的解决方案,不涉及从 Compojure 复制一大块代码。

FWIW, I got this to work by using Ring's wrap-file-info middleware; I'm sorta embarrassed that I looked for this in Compojure instead of Ring. However, compojure.route's files and resources handlers both serve up streams instead of Files or URLs, and of course Ring can't figure out metadata from that.

I had to write basically a copy of resources that returns a File instead; when wrapped in wrap-file-info that met my needs. Still wouldn't mind a slightly better solution that doesn't involve copying a chunk of code from Compojure.

灼疼热情 2024-11-16 20:25:58

您是否考虑过使用ring-etag-middleware?它使用文件的最后修改日期来生成实体标签。然后,它将匹配请求中的 if-none-match 标头时键入 304。

Have you considered using the ring-etag-middleware? It uses the last modified date of a file to generate the entity tag. It then keys a 304 on a match to the if-none-match header in the request.

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