防止浏览器缓存JavaScript文件的更好方法

防止浏览器缓存JavaScript文件的更好方法,javascript,jquery,css,caching,jsp,Javascript,Jquery,Css,Caching,Jsp,这就是我们防止浏览器缓存JS和CSS文件的方法。这似乎有点令人讨厌。。有更好的办法吗 <% //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

这就是我们防止浏览器缓存JS和CSS文件的方法。这似乎有点令人讨厌。。有更好的办法吗

<%
//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> 



更新:我们阻止缓存的原因是为了确保在发布新版本时加载文件的更新版本。

缓存是您的朋友。如果浏览器不正确地缓存这些文件,则意味着web服务器与JS和CSS文件一起发送的HTTP头(而不是使用它们的HTML页面)有问题。浏览器使用这些标题确定是否可以缓存文件

您的Web服务器可以发送这些标题(在它所服务的每个JS和CSS文件上),告诉浏览器不要缓存它们:

Cache-Control: no-cache
Pragma: no-cache
Expires: Sat, 01 Jan 2000 00:00:00 GMT
但这会增加网站的网络负载,用户会看到页面负载变慢。您可以稍微宽容一点,允许浏览器将CSS文件缓存60秒:

Cache-Control: max-age=60
如果您确实希望浏览器在每次加载页面时检查新文件,您仍然可以使用ETag来节省一些网络流量:

Cache-Control: max-age=0
Pragma: no-cache
Expires: Sat, 01 Jan 2000 00:00:00 GMT
ETag: "o2389r-98ur0-w3894tu-q894"
ETag只是每次文件更改时Web服务器组成的唯一标识符。下一次浏览器需要该文件时,它会询问服务器,“/js/pm.init.js是否仍有ETag o2389r98ur0w3894tuq894?”如果是,服务器只会说“是”。这样,服务器就不必再次发送整个文件,用户也不必等待文件加载。双赢

如何说服web服务器自动生成ETag取决于服务器。这通常并不难


我以前见过你使用的黑客。与Web上的许多内容一样,它并不漂亮,也不是特别有效,但它可以工作。

您希望缓存CSS和JS。当他们回来时,它会加快网页的加载速度。添加时间戳后,您的用户将被迫一次又一次地下载它

如果你想确保他们总是有一个新的版本,那就让你的构建系统在文件的末尾添加一个构建号,而不是时间戳


如果您在开发中遇到问题,请确保将浏览器设置为不缓存文件,或将开发页面上的标题设置为不缓存。

出于调试目的,请安装FireFox并在其中激活“停用缓存”

更新:
当您安装了FireBug时,您可以。

如果我们想要阻止缓存的原因是为了确保在执行新版本时加载较新版本的文件,那么您希望在有新版本时加载新的js,而不是所有时候

为此,您希望“ts”值与文件链接,而不是与一天中的时间链接。 您可以使用以下系统之一:

  • ts=文件的时间戳
  • ts=文件的MD5(或任何校验和)
  • ts=代码的版本。如果您有一个执行部署的脚本,请确保它在将分配给ts的一些包含文件中添加了版本代码(或发布日期)

  • 通过这种方式,浏览器将仅在文件是新的且并非总是新的情况下重新加载该文件。

    一种简单的方法是在URL中使用js或css文件的最后修改日期,而不是时间戳。只有当服务器上有新版本的文件时,这才有防止缓存的效果

    编辑

    在使用SpringBoot的情况下,现在更容易防止缓存修改过的文件

    您只需将其添加到application.properties:

    spring.resources.chain.strategy.content.enabled=true
    spring.resources.chain.strategy.content.paths=/**
    
    如果您使用的是Thymeleaf或FreeMarker,它将完全自动配置。如果您使用的是JSP,则需要手动声明ResourceUrEncodingFilter

    请在此处阅读更多信息:

    下面是我的“旧”帖子,它也可以,但需要更多的工作


    因为您使用的是Java,所以也有可能使用maven来管理您的项目

    在这种情况下,为了提高性能,并确保在生成软件的新版本时浏览器不会缓存静态资源,您应该将所有样式表和JavaScript文件合并到其类型的单个文件中,并且在创建新版本时,您应该更改资源URL

    幸运的是,maven可以在构建时为您完成所有这些。您需要
    minifymaven插件
    maven替换插件

    这篇pom.xml摘录应该让您开始:

    <properties>
        <timestamp>${maven.build.timestamp}</timestamp>
        <maven.build.timestamp.format>yyyyMMddHHmm</maven.build.timestamp.format>
    </properties>
    
    <plugin>
        <groupId>com.samaxes.maven</groupId>
        <artifactId>minify-maven-plugin</artifactId>
        <version>1.6</version>
        <executions>
            <execution>
                <id>minify-css</id>
                <phase>process-resources</phase>
                <goals>
                    <goal>minify</goal>
                </goals>
                <configuration>
                    <linebreak>-1</linebreak>
                    <cssSourceDir>resources/css</cssSourceDir>
                    <cssSourceFiles>
                        <cssSourceFile>bootstrap.css</cssSourceFile>
                        <cssSourceFile>style.css</cssSourceFile>
                    </cssSourceFiles>
                    <cssTargetDir>resources/css</cssTargetDir>
                    <cssFinalFile>${timestamp}.css</cssFinalFile>
                </configuration>
            </execution>
            <execution>
                <id>minify-js</id>
                <phase>process-resources</phase>
                <goals>
                    <goal>minify</goal>
                </goals>
                <configuration>
                    <linebreak>-1</linebreak>
                    <jsSourceDir>resources/js</jsSourceDir>
                    <jsSourceFiles>
                        <jsSourceFile>jquery.js</jsSourceFile>
                        <jsSourceFile>bootstrap.js</jsSourceFile>
                        <jsSourceFile>script.js</jsSourceFile>
                    </jsSourceFiles>
                    <jsTargetDir>resources/js</jsTargetDir>
                    <jsFinalFile>${timestamp}.js</jsFinalFile>
                </configuration>
            </execution>
        </executions>
    </plugin>
    
    <plugin>
        <groupId>com.google.code.maven-replacer-plugin</groupId>
        <artifactId>replacer</artifactId>
        <version>1.5.2</version>
        <executions>
            <execution>
                <id>replaceDynPartInResourcePath</id>
                <phase>prepare-package</phase>
                <goals>
                    <goal>replace</goal>
                </goals>
                <configuration>
                    <ignoreMissingFile>false</ignoreMissingFile>
                    <basedir>${project.build.directory}</basedir>
                    <file>${project.artifactId}/WEB-INF/views/header.jsp</file>
                    <regex>false</regex>
                    <replacements>
                        <replacement>
                            <token>$dynamicResourceNamePart$</token>
                            <value>${timestamp}</value>
                        </replacement>
                    </replacements>
                </configuration>
            </execution>
        </executions>
    </plugin>
    
    
    ${maven.build.timestamp}
    yyyyMMddHHmm
    com.samaxes.maven
    缩小maven插件
    1.6
    缩小css
    过程资源
    缩小
    -1
    资源/css
    bootstrap.css
    样式表
    资源/css
    ${timestamp}.css
    缩小js
    过程资源
    缩小
    -1
    资源/js
    jquery.js
    bootstrap.js
    script.js
    资源/js
    ${timestamp}.js
    com.google.code.maven-replacer-plugin
    替代者
    1.5.2
    替换资源路径
    准备包装
    代替
    假的
    ${project.build.directory}
    ${project.artifactId}/WEB-INF/views/header.jsp
    假的
    $dynamicResourceNamePart$
    ${timestamp}
    
    这是如何在header.jsp中包含静态资源

    <c:choose>
        <c:when test="${not fn:contains(pageContext.request.serverName, 'localhost') and empty param.nocombine}">
            <link href="${pageContext.request.contextPath}/resources/css/$dynamicResourceNamePart$.min.css" rel="stylesheet" type="text/css" />
            <script src="${pageContext.request.contextPath}/resources/js/$dynamicResourceNamePart$.min.js" type="text/javascript"></script>
        </c:when>
        <c:otherwise>
            <link href="${pageContext.request.contextPath}/resources/css/bootstrap.css" rel="stylesheet">
            <link href="${pageContext.request.contextPath}/resources/css/style.css" rel="stylesheet">
            <script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/jquery.js"></script>
            <script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/bootstrap.js"></script>
            <script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/script.js"></script>
        </c:otherwise>
    </c:choose>