防止浏览器缓存 JavaScript 文件的更好方法
这就是我们防止浏览器缓存 JS 和 CSS 文件的方法。这看起来有点hacky..有更好的方法吗?
<%
//JSP code
long ts = (new Date()).getTime(); //Used to prevent JS/CSS caching
%>
<link rel="stylesheet" type="text/css" media="screen" href="/css/management.css?<%=ts %>" />
<script type="text/javascript" src="/js/pm.init.js?<%=ts %>"></script>
<script type="text/javascript" src="/js/pm.util.func.js?<%=ts %>"></script>
更新:我们想要防止缓存的原因是确保在发布新版本时加载较新版本的文件。
This is how we prevent caching of JS and CSS files by browsers. This seems slightly hacky.. is there a better way?
<%
//JSP code
long ts = (new Date()).getTime(); //Used to prevent JS/CSS caching
%>
<link rel="stylesheet" type="text/css" media="screen" href="/css/management.css?<%=ts %>" />
<script type="text/javascript" src="/js/pm.init.js?<%=ts %>"></script>
<script type="text/javascript" src="/js/pm.util.func.js?<%=ts %>"></script>
Update: The reason we want to prevent caching is to ensure the newer version of the files are loaded when we do a new release.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
您希望 CSS 和 JS 被缓存。当他们回来时,它可以加快网页的加载速度。添加时间戳后,您的用户将被迫一次又一次地下载它。
如果您想确保它们始终具有新版本,请让您的构建系统在文件末尾添加构建号而不是时间戳。
如果您在开发中遇到问题,请确保将浏览器设置为不缓存文件,或将开发页面上的标头设置为不缓存。
You want CSS and JS to be cached. It speeds up the loading of the web page when they come back. Adding a timestamp, your user's will be forced to download it time and time again.
If you want to make sure they always have a new version, than have your build system add a build number to the end of the file instead of a timestamp.
If you have issues with it just in dev, make sure to set up your browsers to not cache files or set headers on your dev pages to not cache.
缓存是你的朋友。如果浏览器错误地缓存这些文件,则意味着您的 Web 服务器与 JS 和 CSS 文件本身(而不是使用它们的 HTML 页面)一起发送的 HTTP 标头有问题。浏览器使用这些标头来确定是否可以缓存该文件。
您的 Web 服务器可以发送这些标头(在它提供的每个 JS 和 CSS 文件上)来告诉浏览器不要缓存它们:
但这会增加您网站上的网络负载,用户会发现页面加载速度变慢。您可以更宽松一点,允许浏览器缓存 CSS 文件 60 秒:
如果您确实希望浏览器在每次加载页面时检查新文件,您仍然可以保存一些使用 ETag 的网络流量:
ETag 只是您的 Web 服务器每次文件更改时组成的唯一标识符。下次浏览器需要该文件时,它会询问服务器“/js/pm.init.js 是否仍有 ETag o2389r98ur0w3894tuq894?”如果是这样,您的服务器只会说“是”。这样您的服务器就不必再次发送整个文件,用户也不必等待它加载。双赢。
如何说服您的 Web 服务器自动生成 ETag 取决于服务器。通常并不难。
我以前见过你使用的 hack。就像网络上的很多东西一样,它不是很漂亮,也不是特别高效,但它确实有效。
Caching is your friend. If browsers are caching these files incorrectly, it means something is wrong with the HTTP headers your web server is sending along with the JS and CSS files themselves (not the HTML page that uses them). The browser uses those headers to figure out if it can cache the file.
Your Web server can send these headers (on every JS and CSS file it serves) to tell browsers not to cache them:
But that will increase the network load on your site, and users will see the page load slower. You could be a little more lenient and allow the browser to cache the CSS file for 60 seconds:
If you really want the browser to check for a new file with every single page load, you can still save some network traffic by using an ETag:
The ETag is simply a unique identifier your Web server makes up each time the file changes. The next time the browser wants the file, it asks the server, "does /js/pm.init.js still have the ETag o2389r98ur0w3894tuq894?" and if so, your server simply says, "yes". That way your server doesn't have to send the whole file again, and the user doesn't have to wait for it to load. Win-win.
How to convince your web server to autogenerate ETags depends on the server. It's usually not hard.
I've seen the hack you're using before. Like so much on the Web, it's not pretty or particularly efficient, but it works.
如果我们想要防止缓存的原因是为了确保在我们发布新版本时加载较新版本的文件。,您希望在有新版本时加载新的 js,而不是所有的时间。
为了做到这一点,您希望“ts”值与文件链接,而不是与一天中的时间链接。
您可以使用以下系统之一:
这样,浏览器仅在文件是新的时才会重新加载该文件,而不是每次都重新加载。
If The reason we want to prevent caching is to ensure the newer version of the files are loaded when we do a new release., you want that the new js is loaded when THERE IS a NEW release, not all the times.
In order to do that you want that the "ts" value is linked with the file not with the time of the day.
You can either use one of these system:
In this way the browser will reload the file only if it is new and not all the times.
一个简单的方法是使用 URL 中 js 或 css 文件的上次修改日期而不是时间戳。仅当服务器上有新版本的文件时,这才会起到阻止缓存的作用。
A simple approach to this would be to use last modified date of the js or css files in the URL instead of a time stamp. This would have the effect of preventing caching only when there is a new version of the file on the server.
编辑
如果您使用 Spring Boot,现在可以更简单地防止缓存已修改的文件。
您需要做的就是将其添加到 application.properties:
如果您使用 Thymeleaf 或 FreeMarker,它是完全自动配置的。如果您使用 JSP,则需要手动声明 ResourceUrlEncodingFilter。
在这里阅读更多内容:
现在下面是我的“旧”帖子,它也可以工作,但需要更多工作。
由于您使用的是 Java,因此您也有可能使用 Maven 来管理您的项目。
在这种情况下,为了提高性能,并确保在生成软件的新版本时没有浏览器缓存您的静态资源,您应该将所有样式表和 JavaScript 文件合并到其类型的单个文件中,并且您应该创建新版本时更改资源 URL。
幸运的是,maven 可以在构建时为您完成所有这些工作。您需要
minify-maven-plugin
和maven-replacer-plugin
。pom.xml 的摘录应该可以帮助您入门:
This is how to include your static resources in header.jsp
Edit
In case you are using Spring Boot it's now much simpler to prevent caching of modified files.
All you need to do is add this to application.properties:
If you are using Thymeleaf or FreeMarker it's completely autoconfigured. If you are using JSPs you need to manually declare a ResourceUrlEncodingFilter.
Read more here:
http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-web-applications.html#boot-features-spring-mvc-static-content
What follows now is my "old" post which also works but requires more work.
Since you are using Java there is a chance you are also using maven to manage your project.
In that case, to improve performance, and to make sure that no browser caches your static resources when a new release of your software is produced, you should combine all of your stylesheets and JavaScript files into on single file of their type, and you should make your resource urls change when you create a new release.
Luckily maven can do all this for you at build-time. You'll need
minify-maven-plugin
andmaven-replacer-plugin
.This excerpt of a pom.xml should get you started:
This is how to include your static resources in header.jsp
出于调试目的,请安装 FireFox 的Web 开发人员工具栏并在那里激活“停用缓存”
更新:
安装 FireBug 后,您可以在网络选项卡设置中禁用缓存。
For debug purposes, install the web developer toolbar for FireFox and activate there "deactivate Cache"
Update:
When you have FireBug installed, you can disable caching as well in the network tab settings.
如果您可以在应用程序中包含 Java Servlet Filter,这里有一个可行的解决方案: CorrectBrowserCacheHandlerFilter.java
基本上,当您的浏览器请求静态文件时,服务器会将每个请求重定向到同一个请求,但带有哈希查询参数(例如
?v=azErT
),该参数取决于静态文件的内容目标静态文件。这样做,浏览器将永远不会缓存在
index.html
中声明的静态文件(因为总是会收到302 Moved Temporarily
),而只会缓存那些与哈希版本(服务器将为他们回答200
)。因此,对于那些具有哈希版本的静态文件,浏览器缓存将得到有效利用。免责声明:我是
CorrectBrowserCacheHandlerFilter.java
的作者。If you can include Java Servlet Filter in your application, here is a working solution: CorrectBrowserCacheHandlerFilter.java
Basically, when your browser requests the static files, the server will redirect every requests to the same one but with a hash query parameter (
?v=azErT
for example) which depends on the content of the target static file.Doing this, the browser will never cache the static files declared in your
index.html
for example (because will always received a302 Moved Temporarily
), but will only cache the ones with the hash version (the server will answer200
for them). So the browser cache will be used efficiently for those static files with hash version.Disclaimer: I'm the author of
CorrectBrowserCacheHandlerFilter.java
.