Việc gắn thêm những gì? V = 1 đối với các URL CSS và Javascript trong các thẻ liên kết và tập lệnh làm gì?


138

Tôi đã xem xét một mẫu soạn sẵn HTML 5 (từ http://html5boilerplate.com/ ) và nhận thấy việc sử dụng "?v=1"URL trong khi tham khảo các tệp CSS và Javascript.

  1. Việc gắn "?v=1"vào các URL CSS và Javascript trong thẻ liên kết và tập lệnh làm gì?
  2. Không phải tất cả các URL Javascript đều có "?v=1"(ví dụ từ mẫu bên dưới js/modernizr-1.5.min.js:). Có một lý do tại sao đây là trường hợp?

Mẫu từ họ index.html:

<!-- CSS : implied media="all" -->
<link rel="stylesheet" href="css/style.css?v=1">

<!-- For the less-enabled mobile browsers like Opera Mini -->
<link rel="stylesheet" media="handheld" href="css/handheld.css?v=1">

<!-- All JavaScript at the bottom, except for Modernizr which enables HTML5 elements & feature detects -->
<script src="js/modernizr-1.5.min.js"></script>

<!------ Some lines removed ------>

<script src="js/plugins.js?v=1"></script>
<script src="js/script.js?v=1"></script>

<!--[if lt IE 7 ]>
  <script src="js/dd_belatedpng.js?v=1"></script>
<![endif]-->


<!-- yui profiler and profileviewer - remove for production -->
<script src="js/profiling/yahoo-profiling.min.js?v=1"></script>
<script src="js/profiling/config.js?v=1"></script>
<!-- end profiling code -->

Câu trả lời:


175

Chúng thường là để đảm bảo rằng trình duyệt có phiên bản mới khi trang web được cập nhật với phiên bản mới, ví dụ như là một phần của quá trình xây dựng của chúng tôi, chúng tôi sẽ có một cái gì đó như thế này:

/Resources/Combined.css?v=x.x.x.buildnumber

Vì điều này thay đổi với mỗi lần đẩy mã mới, khách hàng buộc phải lấy một phiên bản mới, chỉ vì chuỗi truy vấn. Nhìn vào trang này (tại thời điểm trả lời này), ví dụ:

<link ... href="http://sstatic.net/stackoverflow/all.css?v=c298c7f8233d">

Tôi nghĩ thay vì số sửa đổi, nhóm SO đã sử dụng hàm băm, đây là cách tiếp cận tốt hơn, ngay cả với bản phát hành mới, các trình duyệt chỉ buộc phải lấy phiên bản mới khi tệp thực sự thay đổi.

Cả hai cách tiếp cận này đều cho phép bạn đặt tiêu đề bộ đệm thành một cái gì đó dài một cách lố bịch, giả sử là 20 năm ... nhưng khi nó thay đổi, bạn không phải lo lắng về tiêu đề bộ đệm đó, trình duyệt thấy một chuỗi truy vấn khác và coi nó như một chuỗi truy vấn khác khác nhau, tập tin mới.


3
@Free - Tiêu đề kiểm soát bộ đệm được gửi ngày hôm qua không thể cho khách hàng biết tệp đã thay đổi ngày hôm nay (khách hàng thậm chí sẽ không kiểm tra), một URL có thể. Bạn có thể giải thích những gì tôi đang thiếu ở đó?
Nick Craver

8
@Free - Cách các tệp này được lưu trong bộ nhớ cache là mãi mãi , có nghĩa là máy khách không có cách nào kiểm tra xem tệp có bị sửa đổi hay không. Điều này có nghĩa là họ sẽ không bao giờ nhận được tệp cập nhật ... trừ khi URL thay đổi, đó là điều xảy ra với kỹ thuật trên. Bạn nhận được tuổi thọ bộ nhớ cache tối đa trên máy khách (ít yêu cầu HTTP nhất) nhưng máy khách được cập nhật ngay lập tức khi tệp thực sự thay đổi . Chính xác làm thế nào bạn sẽ thực hiện tất cả điều này bằng cách chỉ sử dụng các tiêu đề kiểm soát bộ đệm?
Nick Craver

4
@Free - Stack Overflow được 5 triệu du khách mỗi tháng, cách tiếp cận của bạn sẽ có 2 tác động: a) nhiều yêu cầu hơn và dữ liệu được gửi đến / từ các máy chủ của chúng tôi, và b) người sử dụng sẽ không ngay lập tức có được mới JavaScript / CSS (ví dụ khi chúng tôi gặp lỗi hoặc các thay đổi HTML cần có JS / CSS mới). Hết hạn tự nhiên thực sự không phải là một lựa chọn ở đây. Phương pháp mà bạn đề xuất sẽ kém hiệu quả về mặt kỹ thuật và kết quả là lỗi người dùng thực tế , trên cơ sở thường xuyên ... không thực sự được chấp nhận trên bất kỳ trang web lớn nào (cũng không nên thực sự là bất kỳ trang web nào ).
Nick Craver

2
@Free - 5 triệu là 5 triệu khách truy cập mỗi tháng , vì chúng tôi triển khai nhiều lần trong ngày , các yêu cầu nhiều lần. Về mặt tải trang HTML, chúng tôi đang nói về hơn 110 triệu một tháng (và đang phát triển ... một lần nữa, đó chỉ là tải trang HTML). Đối với a) có, nhiều hơn hoặc nhiều lần nghỉ hơn, đó là một sự đánh đổi theo thời gian bộ nhớ cache so với các máy khách có nội dung chính xác. Ngoài ra, logic của bạn cho b) còn thiếu sót, html không được lưu trong bộ nhớ cache, do đó, được sử dụng với bộ nhớ cache mà không còn hoạt động nghĩa là chỉ người dùng được lưu trong bộ nhớ cache bị ảnh hưởng, không phải là họ miễn dịch.
Nick Craver

5
@GMsoF v chỉ đại diện cho "phiên bản" đối với chúng tôi, đó là một sự lựa chọn hoàn toàn tùy ý. Bất kỳ chuỗi truy vấn giá trị nào cũng sẽ hoạt động, ví dụ: nó có thể dễ dàng như vậy? Jejdutogjesudo =
Nick Craver

23

Điều này đảm bảo bạn sẽ nhận được phiên bản mới nhất từ ​​tệp css hoặc js từ máy chủ.

Và sau này bạn có thể nối thêm "?v=2"nếu bạn có phiên bản mới hơn "?v=3", "?v=4", v.v.

Lưu ý rằng bạn có thể sử dụng bất kỳ querystring, 'v' không phải là một ví dụ bắt buộc:

"?blah=1"Sẽ hoạt động tốt.

"?xyz=1002" sẽ làm việc.

Và đây là một kỹ thuật phổ biến vì các trình duyệt hiện đang lưu các tệp js và css tốt hơn và lâu hơn.


13

Giải pháp băm là tốt nhưng không thực sự có thể đọc được khi bạn muốn biết phiên bản nào của tệp đang nằm trong thư mục web cục bộ của bạn. Giải pháp làdate/time đóng dấu phiên bản của bạn để bạn có thể dễ dàng so sánh nó với tệp máy chủ của mình.

Ví dụ: nếu .js or .csstệp của bạn là ngày2011-02-08 15:55:30 (sửa đổi lần cuối) thì phiên bản sẽ bằng.js?v=20110208155530

Nên dễ đọc các thuộc tính của bất kỳ tệp nào trong bất kỳ ngôn ngữ nào. Trong ASP.Net thật dễ dàng ...

".js?v=" + File.GetLastWriteTime(HttpContext.Current.Request.PhysicalApplicationPath + filename).ToString("yyMMddHHHmmss");

Coz làm cho nó được tái cấu trúc độc đáo thành các thuộc tính / chức năng đầu tiên và tắt đi. Không còn lời bào chữa nào nữa.

Chúc may mắn, Nghệ thuật.


2
Điều gì sẽ xảy ra nếu bạn đang xây dựng trang web của mình chỉ với html js và css. Sau đó, làm thế nào chúng ta có thể tự động tiêm tên phiên bản vào tài nguyên tĩnh?
Nishanth Nair

@ Whizkid747 trả lời trễ, nhưng đối với người mới, bất kỳ hệ thống xây dựng / xây dựng trang web nào bạn đang sử dụng nên có cách lấy ngày tính bằng mili giây mà bạn có thể sử dụng làm phiên bản, nếu không thì bạn không sử dụng hệ thống xây dựng // xây dựng bạn phải tự viết những thứ này
AntK

7

Các tệp Javascript thường được trình duyệt lưu vào bộ nhớ cache lâu hơn nhiều so với bạn mong đợi.

Điều này thường có thể dẫn đến hành vi không mong muốn khi bạn phát hành phiên bản mới của tệp JS.

Do đó, thông thường là thêm tham số QueryString vào URL cho tệp javascript. Bằng cách đó, trình duyệt lưu trữ tệp Javascript với v = 1. Khi bạn phát hành phiên bản mới của tệp javascript, bạn thay đổi url thành v = 2 và trình duyệt sẽ buộc phải tải xuống một bản sao mới.


trình duyệt nào chính xác? thậm chí hầu hết các IE 5 và 6 kỳ quặc đều tuân theo các tiêu đề kiểm soát bộ đệm.
Tư vấn miễn phí

7

Để trả lời bạn câu hỏi;

"? v = 1" điều này chỉ được viết bằng beacuse để tải xuống một bản sao mới của các tệp css và js thay vì sử dụng từ bộ đệm của trình duyệt.

Nếu bạn đề cập đến tham số chuỗi truy vấn này ở cuối biểu định kiểu hoặc tệp js thì nó buộc trình duyệt tải xuống một tệp mới, do đó những thay đổi gần đây trong tệp .css và .js được thực hiện trong trình duyệt của bạn.

Nếu bạn không sử dụng phiên bản này thì bạn có thể cần xóa bộ nhớ cache làm mới trang để xem các thay đổi gần đây trong các tệp đó.

Dưới đây là một bài viết giải thích điều này Làm thế nào và tại sao để tạo phiên bản của các tệp CSS và JS


2

Trong quá trình phát triển / thử nghiệm các bản phát hành mới, bộ đệm có thể là một vấn đề vì trình duyệt, máy chủ và thậm chí đôi khi là telco 3G (nếu bạn triển khai trên thiết bị di động) sẽ lưu trữ nội dung tĩnh (ví dụ: JS, CSS, HTML, img). Bạn có thể khắc phục điều này bằng cách nối thêm số phiên bản, số ngẫu nhiên hoặc dấu thời gian vào URL, ví dụ: JSP:<script src="js/excel.js?time=<%=new java.util.Date()%>"></script>

Trong trường hợp bạn đang chạy HTML thuần túy (thay vì các trang máy chủ JSP, ASP, PHP), máy chủ sẽ không giúp bạn. Trong trình duyệt, các liên kết được tải trước khi chạy JS, do đó bạn phải xóa các liên kết và tải chúng bằng JS.

// front end cache bust
var cacheBust = ['js/StrUtil.js', 'js/protos.common.js', 'js/conf.js', 'bootstrap_ECP/js/init.js'];   
for (i=0; i < cacheBust.length; i++){
     var el = document.createElement('script');
     el.src = cacheBust[i]+"?v=" + Math.random();
     document.getElementsByTagName('head')[0].appendChild(el);
}

0

Như bạn có thể đọc trước đây, ?v=1 đảm bảo rằng trình duyệt của bạn có được phiên bản 1 của tệp. Khi bạn có một phiên bản mới, bạn chỉ cần thêm một số phiên bản khác và trình duyệt sẽ quên phiên bản cũ và tải phiên bản mới.

Có một plugin gulp chăm sóc phiên bản các tệp của bạn trong giai đoạn xây dựng, vì vậy bạn không phải thực hiện thủ công. Thật tiện dụng và bạn có thể dễ dàng tích hợp nó trong quá trình xây dựng. Đây là liên kết: gulp-annotate


-2

Như đã đề cập bởi những người khác, điều này được sử dụng để phá vỡ bộ nhớ cache phía trước. Để thực hiện điều này, cá nhân tôi thấy gói npm grunt-cache-bust hữu ích.


1
Mặc dù liên kết này có thể trả lời câu hỏi, nhưng câu trả lời chỉ liên kết không được khuyến khích trên Stack Overflow, bạn có thể cải thiện câu trả lời này bằng cách lấy các phần quan trọng của liên kết và đưa nó vào câu trả lời của bạn, điều này đảm bảo câu trả lời của bạn vẫn là câu trả lời nếu liên kết bị thay đổi hoặc bị xóa :)
WhatsThePoint
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.