我正在为 CSS/Javascript 设置远期过期标头,以便浏览器在缓存文件后就不会再次请求这些文件。我还有一个简单的版本控制机制,这样如果文件发生更改,客户端就会知道。
基本上我有一个模板标签,我做了类似
将变为
。
模板标记打开一个文件javascript/c/c.js.v
,在其中查找版本号并将其附加到查询字符串。该版本由 shell 脚本生成(目前手动运行,可能会添加预提交挂钩),该脚本检查文件是否已更改(使用 git diff)。
这一切都工作正常,除了:
我也想为图像实现相同类型的版本控制。但图像可以从 CSS 引用 - 这是一个静态文件(由 nginx 提供) - 所以那里没有模板标签。
文件版本控制的更好方法是什么?
或者,我正在考虑用中间件替换模板标签,该中间件在返回响应之前更改所有链接。这比模板标记要好,模板标记可能会被错误地省略。但仍然没有解决CSS引用图像的问题。
另外,我知道将版本作为查询字符串的一部分可能会导致某些代理不缓存文件而出现问题 - 因此我考虑将版本作为文件名的一部分 - 例如 javascript/c/c.123456 .js
。
注意:看起来没有办法使用 Django 解决这个问题(显然 - 因为我什至不通过 Django 提供 CSS)。但必须有一个解决方案,也许涉及一些 nginx 技巧。
I am setting far-future expires headers for my CSS/Javascript so that the browsers don't ever ask for the files again once they get cached. I also have a simple versioning mechanism so that if the files change, the clients will know.
Basically I have a template tag and I do something like
<script type="text/javascript" src="{{ MEDIA_URL }}{% versioned "javascript/c/c.js" %}"></script>
which will become
<script type="text/javascript" src="http://x.com/media/javascript/c/c.min.js?123456"></script>
.
The template tag opens a file javascript/c/c.js.v
where it finds the version number and appends it to the query string. The version is generated by a shell script (run manually for now, will probably add pre-commit hook) which checks whether the file has changed (using git diff
).
This is all working fine, EXCEPT:
I want to implement the same kind of versioning for images as well. But images can be referenced from CSS - which is a static file (served by nginx) - so no template tag there.
What is a better approach for file versioning?
Alternatively, I am thinking about replacing the template tag with a middleware which changes all links before returning the response. That is better than the template tag, which can be mistakenly omitted. But still doesn't solve the issue of images referenced from CSS.
Also, I'm aware that having the version as part of the query string might cause trouble with certain proxies not caching the file - so I consider making the version part of the filename - for example javascript/c/c.123456.js
.
Note: It looks like there is no way to solve this issue using Django (obviously - since I don't even serve the CSS through Django). But there has to be a solution, perhaps involving some nginx tricks.
发布评论
评论(5)
样式表资源
对于样式表引用的资源,最好使用 Sass 和 Sass。罗盘。 Compass 有一个 mixin,它会自动在样式表中引用的静态资源末尾添加版本查询参数。仅当您重建样式表时,版本号才会发生变化(在本地开发时,这对于
compass watch
来说是微不足道的)。模板资源
对于其他文件,我实际上会使用某种后拉钩子来重写 python 模块,其唯一目的是包含当前版本。
您的帖子拉钩将创建:
其中包含最新(或以前)的 git commit 哈希:
然后在您的
settings.live
中使用简单的from .version import __version__ as ApplicationVersion
,您的模板标记可以简单地使用from settings import ApplicationVersion
将该查询参数写入为缓存破坏程序。Stylesheet Assets
For your stylesheet referenced assets, you're much better off using Sass & Compass. Compass has a mixin that will automatically add version query parameters on the end of static assets referenced within a stylesheet. The version number only changes when you rebuild the stylesheet (which is trivial with
compass watch
while you develop locally).Template Assets
For other files, I would actually use a post-pull hook of some kind that rewrites a python module whose sole purpose is to contain the current version.
Your post pull hook would create :
Which would contain the latest (or previous) git commit hash :
Then with a simple
from .version import __version__ as ApplicationVersion
in yoursettings.live
, your template tag can simply usefrom settings import ApplicationVersion
to write that query parameter as teh cache buster.我们使用这个简单的模板标签根据文件修改时间生成版本号:
对于 1.3 之前的 Django,该标签还有更简单的版本:
用法:
We are using this simple templatetag to generate version number based on file modification time:
For pre 1.3 Django there is even simpler version of this tag:
Usage:
将在我的预提交脚本中添加另一个步骤,以将所有直接链接替换为最小化 CSS 中版本化文件的链接。
看来没有更好的办法了。如果您想到任何答案,请告诉我,我会考虑将该答案标记为已接受的答案。
感谢您的评论!
Will add another step to my pre-commit script to replace all direct links with links to versioned files in the minimized CSS.
Seems there is no better way to do it. If you think of any, let me know and I'll consider marking that one as accepted answer.
Thanks for your comments!
这也可能有帮助:http://www.fanstatic.org/
This might help as well: http://www.fanstatic.org/
我认为一个简单的解决方案可能是:
I think a simple solution might be: