2010-11-17 69 views
20

Đây là cách chúng tôi ngăn chặn lưu vào bộ nhớ cache của các tệp JS và CSS theo trình duyệt. Điều này có vẻ hơi hacky .. là có một cách tốt hơn?Cách tốt hơn để ngăn chặn bộ nhớ đệm của trình duyệt của các tệp JavaScript

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

Cập nhật: Lý do chúng tôi muốn ngăn chặn bộ nhớ đệm là để đảm bảo các phiên bản mới hơn của các tập tin được nạp khi chúng ta làm một phiên bản mới.

+3

Họ có cần tìm nạp mọi tải trang hay chỉ khi bạn thực hiện bản phát hành mới? –

+2

Có lý do tại sao bạn muốn * ngăn chặn * lưu vào bộ nhớ cache nội dung tĩnh của bạn? Điều đó hoàn toàn trái ngược với những gì mọi người thường làm. – Pointy

+2

@Nick Craver & Pointy: Có thể anh ấy đang gỡ lỗi và không muốn xóa bộ nhớ cache mỗi lần? Đó là tất cả những gì tôi có thể hình dung. – Robusto

Trả lời

20

Bạn muốn CSS và JS được lưu vào bộ nhớ cache. Nó tăng tốc độ tải trang web khi họ quay lại. Thêm dấu thời gian, người dùng của bạn sẽ bị buộc tải xuống thời gian và thời gian một lần nữa.

Nếu bạn muốn đảm bảo rằng họ luôn có phiên bản mới, không phải hệ thống xây dựng của bạn thêm số bản dựng vào cuối tệp thay vì dấu thời gian.

Nếu bạn có vấn đề với nó chỉ trong dev, hãy chắc chắn để thiết lập trình duyệt của bạn để không bộ nhớ cache tập tin hoặc đặt tiêu đề trên các trang dev của bạn để không cache.

+0

"Thêm dấu thời gian, người dùng của bạn sẽ bị buộc tải xuống thời gian và thời gian một lần nữa". (Điều này thật ý nghĩa). Nhưng sau đó bạn nói, "Nếu bạn muốn chắc chắn rằng họ luôn luôn có một phiên bản mới, hơn có hệ thống xây dựng của bạn thêm một số xây dựng vào cuối của tập tin thay vì một dấu thời gian." (Điều này có vẻ mâu thuẫn với tuyên bố đầu tiên của bạn). – AlvinfromDiaspar

+1

Yêu thích khi câu hỏi 8 tuổi có nhận xét. Bạn cũng cập nhật mọi lúc, bản cập nhật khác bạn chỉ cập nhật khi thay đổi. Lý tưởng nhất là bạn đặt tiêu đề bộ nhớ cache thích hợp và bạn sẽ không cần phải làm điều đó. – epascarello

17

Caching là bạn của bạn. Nếu trình duyệt đang lưu trong bộ nhớ đệm những tệp này không chính xác, điều đó có nghĩa là đã xảy ra sự cố với tiêu đề HTTP mà máy chủ web của bạn đang gửi cùng với các tệp JS và CSS (không phải trang HTML sử dụng chúng). Trình duyệt sử dụng các tiêu đề đó để tìm hiểu xem nó có thể lưu vào bộ nhớ cache hay không.

máy chủ web của bạn có thể gửi các tiêu đề (trên tất cả các tập tin JS và CSS nó phục vụ) nói với các trình duyệt không để cache họ:

Cache-Control: no-cache 
Pragma: no-cache 
Expires: Sat, 01 Jan 2000 00:00:00 GMT 

Nhưng điều đó sẽ làm tăng tải mạng trên trang web của bạn, và người dùng sẽ xem tải trang chậm hơn. Bạn có thể khoan dung hơn một chút và cho phép trình duyệt để cache file CSS trong 60 giây:

Cache-Control: max-age=60 

Nếu bạn thực sự muốn trình duyệt để kiểm tra một file mới với mỗi tải trang duy nhất, bạn có thể vẫn lưu một số lưu lượng truy cập mạng bằng cách sử dụng ETag:

Cache-Control: max-age=0 
Pragma: no-cache 
Expires: Sat, 01 Jan 2000 00:00:00 GMT 
ETag: "o2389r-98ur0-w3894tu-q894" 

ETag chỉ đơn giản là mã định danh duy nhất mà máy chủ Web của bạn tạo ra mỗi khi tệp thay đổi. Lần sau trình duyệt muốn tệp, nó hỏi máy chủ, "/js/pm.init.js vẫn có ETag o2389r98ur0w3894tuq894?" và nếu vậy, máy chủ của bạn chỉ đơn giản là nói "có". Bằng cách đó, máy chủ của bạn không phải gửi lại toàn bộ tệp và người dùng không phải chờ tải tệp đó. Giành chiến thắng.

Cách thuyết phục máy chủ web của bạn tự động tạo thẻ ETTAG tùy thuộc vào máy chủ. Nó thường không khó.

Tôi đã thấy bản hack bạn đang sử dụng trước đây. Giống như rất nhiều trên trang web, nó không đẹp hoặc đặc biệt hiệu quả, nhưng nó hoạt động.

1

Đối với mục đích gỡ lỗi, cài đặt web developer toolbar cho FireFox và kích hoạt có "tắt Cache"

Cập nhật:
Khi bạn đã cài đặt Firebug, bạn có thể disable caching as well in the network tab settings.

+1

Chúng tôi có một loại công cụ tương tự cho Chrome không? – Raghav

+1

Google Chrome đi kèm với Công cụ dành cho nhà phát triển Chrome được tích hợp trong trình duyệt. nếu bạn mở Công cụ dành cho Chrome Dev, bạn sẽ thấy bánh răng ở góc dưới cùng bên phải. Nhấp vào đó và chọn hộp "Tắt bộ nhớ cache" trong tiêu đề "Chung". – Matt

11

Nếu Lý do chúng tôi muốn ngăn bộ nhớ đệm là đảm bảo phiên bản mới hơn của các tệp được tải khi chúng tôi thực hiện bản phát hành mới., bạn muốn các js mới được tải khi có bản phát hành MỚI, không phải tất cả các lần.

Để thực hiện điều đó, bạn muốn giá trị "ts" được liên kết với tệp không có thời gian trong ngày. Bạn có thể sử dụng một trong những hệ thống:

  1. ts = Timestamp CỦA FILE
  2. ts = MD5 (hoặc bất kỳ checksum) của FILE
  3. ts = phiên bản mã. Nếu bạn có một tập lệnh triển khai hãy chắc chắn rằng nó thêm mã phiên bản (hoặc ngày phát hành) trong một số tệp bao gồm tệp sẽ được gán cho ts.

Bằng cách này, trình duyệt sẽ tải lại tệp chỉ khi mới và không phải tất cả các lần.

3

Cách tiếp cận đơn giản này sẽ là sử dụng ngày sửa đổi cuối cùng của tệp js hoặc css trong URL thay vì dấu thời gian. Điều này sẽ có tác dụng ngăn chặn bộ nhớ đệm chỉ khi có một phiên bản mới của tập tin trên máy chủ.

3

Sửa

Trong trường hợp bạn đang sử dụng Spring Boot nó bây giờ đơn giản hơn nhiều để ngăn chặn bộ nhớ đệm của các tập tin sửa đổi.

Tất cả bạn cần làm là thêm video này vào application.properties:

spring.resources.chain.strategy.content.enabled=true 
spring.resources.chain.strategy.content.paths=/** 

Nếu bạn đang sử dụng Thymeleaf hoặc Freemarker nó hoàn toàn autoconfigured. Nếu bạn đang sử dụng JSP, bạn cần khai báo thủ công ResourceUrlEncodingFilter.

đọc thêm ở đây: http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-web-applications.html#boot-features-spring-mvc-static-content

gì sau giờ tôi bài "cũ" mà cũng làm việc nhưng đòi hỏi phải làm việc nhiều hơn.


Vì bạn đang sử dụng Java nên có khả năng bạn cũng đang sử dụng maven để quản lý dự án của mình. Trong trường hợp đó, để cải thiện hiệu suất và để đảm bảo rằng không có trình duyệt lưu trữ tài nguyên tĩnh của bạn khi phát hành phần mềm mới, bạn nên kết hợp tất cả các tệp định kiểu và tệp JavaScript của mình vào một tệp duy nhất và bạn nên thay đổi url tài nguyên khi tạo bản phát hành mới.

May mắn maven có thể làm tất cả điều này cho bạn tại thời gian xây dựng. Bạn sẽ cần minify-maven-pluginmaven-replacer-plugin.

trích đoạn này của một pom.xml nên giúp bạn bắt đầu:

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

Đây là cách để bao gồm các tài nguyên tĩnh của bạn trong tiêu đề.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> 
0

Nếu bạn có thể bao gồm Java Servlet Filter trong ứng dụng của bạn, đây là một giải pháp làm việc: CorrectBrowserCacheHandlerFilter.java

Về cơ bản, khi trình duyệt của bạn yêu cầu các tập tin tĩnh, máy chủ sẽ chuyển hướng tất cả các yêu cầu đến một cùng nhưng với tham số truy vấn băm (ví dụ: ?v=azErT) phụ thuộc vào nội dung của tệp tĩnh mục tiêu.

Việc làm này, trình duyệt sẽ không bao giờ bộ nhớ cache các file tĩnh khai báo trong index.html của bạn ví dụ (vì sẽ luôn nhận được một 302 Moved Temporarily), nhưng sẽ chỉ bộ nhớ cache là những người có phiên bản băm (máy chủ sẽ trả lời 200 cho họ). Vì vậy, bộ nhớ cache của trình duyệt sẽ được sử dụng hiệu quả cho các tệp tĩnh đó với phiên bản băm.

Tuyên bố từ chối trách nhiệm: Tôi là tác giả của CorrectBrowserCacheHandlerFilter.java.

Các vấn đề liên quan