Cách ngăn chặn bộ nhớ cache của trình duyệt cho trang web php


121

Tôi có một trang web php đang chạy trên máy chủ đám mây. Khi tôi thêm tệp mới css, js hoặc hình ảnh, trình duyệt đang tải cùng một tệp js, css và hình ảnh cũ được lưu trữ trong bộ nhớ cache.

Trang web của tôi có loại tài liệu và thẻ meta như bên dưới

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  <meta http-equiv="Page-Enter" content="blendTrans(Duration=1.0)">
  <meta http-equiv="Page-Exit" content="blendTrans(Duration=1.0)">
  <meta http-equiv="Site-Enter" content="blendTrans(Duration=1.0)">
  <meta http-equiv="Site-Exit" content="blendTrans(Duration=1.0)">

Do loại tài liệu và mã meta ở trên, tôi đang tải các tệp giống nhau được lưu trong bộ nhớ cache trong trình duyệt thay vì tệp mới


No Cache in all Browsers. Bạn cũng có thể thực hiện? RandomGeneratedNumber trên các tệp bạn không muốn lưu vào bộ nhớ đệm.
Kodemon

2
Bạn có thể không muốn tắt hoàn toàn bộ nhớ cache cho hình ảnh / js / css: stackoverflow.com/questions/4206224/…
FoolishSeth

Đã chống lại sự cám dỗ để hoại tử, nhưng làm ơn, bất cứ ai đang cân nhắc điều này: dừng lại. Tìm hiểu cách kiểm soát và sử dụng bộ nhớ đệm, đừng chỉ vô hiệu hóa nó một cách mù quáng vì một tình tiết bất tiện. Đọc chương về Bộ nhớ đệm từ HTTP Hướng dẫn cuối cùng - cuốn sách này (và RFC) phải là bài đọc bắt buộc, có kiểm tra. Tìm hiểu cách chỉ định Sửa lần cuối, trả lời Nếu-Sửa đổi-Kể từ và sử dụng nhận dạng ETag. Sau đó, khi nội dung được cập nhật, các trình duyệt sẽ được thông báo khi 304 đó trở thành 200 một lần nữa.
amcgregor

Câu trả lời:


283

thử cái này

<?php

header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
?>

6
Ngoại trừ "max-age = 0", đó là những tiêu đề được gửi bởi PHP mà không chỉ định những điều trên trong cài đặt của tôi .. Có vẻ như PHP cố gắng ngăn chặn bộ nhớ đệm của trình duyệt theo mặc định ...
phản xạ nhanh

1
Tôi có một plugin WordPress gửi một chủ đề thay thế cho các phiên bản cũ của Internet Explorer và nó đã bị lỗi trên một số hệ thống bộ nhớ đệm. Bài đăng này xuất hiện trên tìm kiếm Google đầu tiên của tôi. Chơi tốt.
Bắt buộc

3
Hãy nhớ rằng điều này không thể được nhúng bên trong html; cái này phải ở đầu trang.
Hunter S

9
Lưu ý: Nếu bạn sử dụng session_start()sau đó, nó sẽ ghi đè tiêu đề của bạn với Cache-Control: private, max-age=10800, pre-check=10800vì 180 phút là giá trị mặc định của session.cache_expire. Nếu bạn không thể tránh bắt đầu phiên, nhưng bạn cần phải tắt sử dụng bộ đệm session_cache_limiter('private');session_cache_expire(0);.
mgutt

2
@thdoan Tham số thứ hai của headerhàm là một boolean để thay thế . Tham số thay thế tùy chọn cho biết liệu tiêu đề sẽ thay thế tiêu đề tương tự trước đó hay thêm tiêu đề thứ hai cùng loại.
mrReiha

36

Tại đây, nếu bạn muốn kiểm soát nó thông qua HTML: hãy làm như bên dưới Tùy chọn 1:

<meta http-equiv="expires" content="Sun, 01 Jan 2014 00:00:00 GMT"/>
<meta http-equiv="pragma" content="no-cache" />

Và nếu bạn muốn kiểm soát nó thông qua PHP: hãy làm như bên dưới Tùy chọn 2:

header('Expires: Sun, 01 Jan 2014 00:00:00 GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', FALSE);
header('Pragma: no-cache');

Tùy chọn 2 LUÔN TỐT HƠN để tránh vấn đề bộ nhớ đệm dựa trên proxy.


10

Bạn có thể thử điều này:

    header("Expires: Tue, 03 Jul 2001 06:00:00 GMT");
    header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
    header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
    header("Cache-Control: post-check=0, pre-check=0", false);
    header("Pragma: no-cache");
    header("Connection: close");

Hy vọng rằng nó sẽ giúp ngăn chặn Cache, nếu có!


Điều này chỉ liên quan đến bộ nhớ đệm của các tệp HTML phải không? Và không liên quan gì đến eTag? Cảm ơn!
Sam Levin

4
chỉ cần dòng đầu tiên là đủ hoàn hảo. Dòng thứ 5 thực sự sai và không liên quan gì đến phản hồi của máy chủ (nó là một tiêu đề yêu cầu). dòng thứ sáu sẽ không có hiệu lực gì. tôi có thể tiếp tục ...
The Surrican

Cách tiếp cận súng ngắn: ném mọi thứ vào tường, hy vọng một thứ gì đó dính vào. Theo nhận xét của tôi về chính câu hỏi, tôi thực sự khuyên bạn nên lấy một bản sao của HTTP: Hướng dẫn Cuối cùng và đọc chương về Bộ nhớ đệm. Cũng là RFC, nhưng đọc chúng là một kỹ năng khác biệt. ("Kết nối: đóng" là một cú sút chân vui nhộn để bao gồm, vô hiệu hóa việc kết nối hiệu quả các yêu cầu hoặc sẽ không làm gì cả, nhưng tôi nghi ngờ PHP có thể thực sự cho phép điều đó.)
amcgregor

7

Tôi gặp sự cố với bộ nhớ đệm các tệp css của mình. Đặt tiêu đề trong PHP không giúp được tôi (có lẽ vì tiêu đề cần được đặt trong tệp biểu định kiểu thay vì liên kết trang với nó?).

Tôi đã tìm thấy giải pháp trên trang này: https://css-tricks.com/can-we-prevent-css-caching/

Giải pháp:

Nối dấu thời gian làm phần truy vấn của URI cho tệp được liên kết.
(Có thể được sử dụng cho css, js, hình ảnh, v.v.)

Cho sự phát triển:

<link rel="stylesheet" href="style.css?<?php echo date('Y-m-d_H:i:s'); ?>">

Đối với sản xuất (nơi bộ nhớ đệm chủ yếu là một điều tốt):

<link rel="stylesheet" type="text/css" href="style.css?version=3.2">
(và viết lại theo cách thủ công khi được yêu cầu)

Hoặc kết hợp cả hai:

<?php
    define( "DEBUGGING", true ); // or false in production enviroment
?>
<!-- ... -->
<link rel="stylesheet" type="text/css" href="style.css?version=3.2<?php echo (DEBUGGING) ? date('_Y-m-d_H:i:s') : ""; ?>">

BIÊN TẬP:

Hoặc sự kết hợp đẹp hơn của hai điều đó:

<?php
    // Init
    define( "DEBUGGING", true ); // or false in production enviroment
    // Functions
    function get_cache_prevent_string( $always = false ) {
        return (DEBUGGING || $always) ? date('_Y-m-d_H:i:s') : "";
    }
?>
<!-- ... -->
<link rel="stylesheet" type="text/css" href="style.css?version=3.2<?php echo get_cache_prevent_string(); ?>">

Phiên bản tùy ý, dấu thời gian hiện tại (đánh bại hoàn toàn bộ nhớ đệm)… nhưng không phải là thứ thực sự có ý nghĩa và hoạt động, bất kể có cờ "gỡ lỗi" hay không. Tại sao bạn không sử dụng mtime thực của tệp? Sau đó, bạn thực sự không bao giờ cần cập nhật PHP, và bộ nhớ đệm sẽ không trở nên hoàn toàn vô dụng. Hoặc chỉ gửi tĩnh của bạn với một máy chủ HTTP được định cấu hình đúng như Nginx hoặc Apache đặt thẻ ETag và Last-Modified thích hợp. Tương tự, loại cờ "gỡ lỗi" đó đã tồn tại… trong trình duyệt. (Tắt bộ nhớ đệm, làm mới mà không có bộ nhớ cache, bộ nhớ đệm trống,…)
amcgregor

5

Ngăn chặn bộ nhớ cache của trình duyệt không phải là một ý kiến ​​hay tùy trường hợp. Đang tìm giải pháp Tôi đã tìm thấy các giải pháp như sau:

<link rel="stylesheet" type="text/css" href="meu.css?v=<?=filemtime($file);?>">

vấn đề ở đây là nếu tệp bị ghi đè trong quá trình cập nhật trên máy chủ, đó là kịch bản của tôi, bộ đệm ẩn sẽ bị bỏ qua vì dấu thời gian được sửa đổi ngay cả khi nội dung của tệp giống nhau.

Tôi sử dụng giải pháp này để buộc trình duyệt chỉ tải xuống nội dung nếu nội dung của nó được sửa đổi:

<link rel="stylesheet" type="text/css" href="meu.css?v=<?=hash_file('md5', $file);?>">

Rất tiếc! Điều này sẽ rất tồi tệ đối với hiệu suất và khả năng mở rộng khi luôn tải tất cả các tệp CSS / JS của bạn trong chuỗi chính để kiểm tra kích thước / băm của chúng.
Dalin

@Dalin Trước khi bạn khóc hết nước mắt của Gentoo ricer (một bản phân phối Linux nổi tiếng với "tốc độ nhanh" do được biên dịch quá mức từ nguồn và điều chỉnh kiến ​​trúc), tôi sẽ statbấm giờ một cuộc gọi. Không có bộ nhớ cache hệ thống tập tin, 16ns, đỉnh? Với bộ nhớ cache, đáng tin cậy <8ns. Nano giây. Và trên hệ thống của tôi, MD5 có thể xử lý 754 MiB / s mà không nhấp nháy. ( openssl speed md5) Kết hợp lại, một tệp CSS 100KB sẽ có tổng chi phí bổ sung kết hợp là… 129µs (micro giây, 0,1295ms) + 8ns (không đóng góp ý nghĩa vào số cuối cùng) = 129µs.
amcgregor

Sau khi xem xét kỹ hơn, tôi thấy rằng câu trả lời "đúng" duy nhất (với gánh nặng bảo trì thấp nhất, hành vi chính xác / đáng tin cậy nhất) vừa là câu trả lời ít được bình chọn nhất, vừa bị bác bỏ trong một nhận xét duy nhất dựa trên cơ sở mỏng manh và không thực tế như vậy.
amcgregor

Bạn và tôi có thể làm việc trên các trang web khác nhau. Nhưng tôi đứng về phía nhận xét của tôi. Nếu có hàng tá chủ đề đồng thời cung cấp các trang web tại bất kỳ thời điểm nào, thì tôi nghĩ có những lựa chọn tốt hơn mà bạn thậm chí sẽ không cần phải đặt câu hỏi liệu nó có thể mở rộng hay không. hash_file('md5', $deployment_counter)hoặc hash_file('md5', $cache_clear_counter)là người đầu tiên nghĩ đến.
Dalin
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.