Câu trả lời:
Một giải pháp phổ biến và đơn giản cho vấn đề có vẻ giống như một cuộc tấn công nhưng khá linh hoạt là thêm một chuỗi truy vấn được tạo ngẫu nhiên vào mỗi yêu cầu cho hình ảnh động.
Ví dụ -
<img src="image.png" />
Sẽ trở thành
<img src="image.png?dummy=8484744" />
Hoặc là
<img src="image.png?dummy=371662" />
Từ quan điểm của máy chủ web, cùng một tệp được truy cập, nhưng từ quan điểm của trình duyệt, không thể thực hiện lưu vào bộ nhớ đệm.
Việc tạo số ngẫu nhiên có thể xảy ra trên máy chủ khi phục vụ trang (chỉ cần đảm bảo rằng bản thân trang đó không được lưu trong bộ nhớ cache ...) hoặc trên máy khách (sử dụng JavaScript).
Bạn sẽ cần xác minh xem máy chủ web của mình có thể đối phó với thủ thuật này hay không.
Các chiến lược bộ nhớ đệm của trình duyệt có thể được kiểm soát bởi các tiêu đề HTTP. Hãy nhớ rằng chúng chỉ là một gợi ý, thực sự. Vì các trình duyệt không nhất quán trong trường này (và bất kỳ trường nào khác), bạn sẽ cần một số tiêu đề để có được hiệu quả mong muốn trên một loạt trình duyệt.
header ("Pragma-directive: no-cache");
header ("Cache-directive: no-cache");
header ("Cache-control: no-cache");
header ("Pragma: no-cache");
header ("Expires: 0");
Nếu bạn cần thực hiện động trong trình duyệt bằng javascript, đây là một ví dụ ...
<img id=graph alt=""
src="http://www.kitco.com/images/live/gold.gif"
/>
<script language="javascript" type="text/javascript">
var d = new Date();
document.getElementById("graph").src =
"http://www.kitco.com/images/live/gold.gif?ver=" +
d.getTime();
</script>
Giải pháp 1 không phải là tuyệt vời.Nó hoạt động, nhưng việc thêm các chuỗi truy vấn ngẫu nhiên hoặc có dấu thời gian vào cuối tệp hình ảnh của bạn sẽ khiến trình duyệt tải xuống lại và lưu vào bộ nhớ cache mọi phiên bản của mọi hình ảnh, mỗi khi trang được tải, bất kể thời tiết hình ảnh có thay đổi hay không trên máy chủ.
Giải pháp 2 là vô ích. Việc thêm nocache
tiêu đề vào tệp hình ảnh không chỉ rất khó thực hiện mà còn hoàn toàn không thực tế vì nó đòi hỏi bạn phải dự đoán trước thời điểm cần thiết , lần đầu tiên bạn tải bất kỳ hình ảnh nào mà bạn nghĩ có thể thay đổi vào một thời điểm nào đó trong tương lai .
Cách tốt nhất mà tôi đã tìm ra để giải quyết vấn đề này là sử dụng ETAGS bên trong tệp .htaccess trong thư mục hình ảnh của bạn. Phần sau yêu cầu Apache gửi một hàm băm duy nhất đến trình duyệt trong tiêu đề tệp hình ảnh. Hàm băm này chỉ thay đổi khi thời gian tệp hình ảnh được sửa đổi và thay đổi này kích hoạt trình duyệt tải lại hình ảnh vào lần tiếp theo khi nó được yêu cầu.
<FilesMatch "\.(jpg|jpeg)$">
FileETag MTime Size
</FilesMatch>
Tôi đã kiểm tra tất cả các câu trả lời và câu trả lời tốt nhất dường như là (không phải):
<img src="image.png?cache=none">
lúc đầu.
Tuy nhiên, nếu bạn thêm cache = none tham số (là từ tĩnh "none") thì không ảnh hưởng gì cả, trình duyệt vẫn tải từ cache.
Giải pháp cho vấn đề này là:
<img src="image.png?nocache=<?php echo time(); ?>">
về cơ bản bạn thêm dấu thời gian unix để làm cho tham số động và không có bộ nhớ cache, nó đã hoạt động.
Tuy nhiên, vấn đề của tôi hơi khác một chút: Tôi đang tải hình ảnh biểu đồ php được tạo nhanh chóng và kiểm soát trang bằng các tham số $ _GET. Tôi muốn hình ảnh được đọc từ bộ nhớ cache khi tham số URL GET giữ nguyên và không lưu vào bộ nhớ cache khi tham số GET thay đổi.
Để giải quyết vấn đề này, tôi cần băm $ _GET nhưng vì nó là mảng nên đây là giải pháp:
$chart_hash = md5(implode('-', $_GET));
echo "<img src='/images/mychart.png?hash=$chart_hash'>";
Chỉnh sửa :
Mặc dù giải pháp trên hoạt động tốt, nhưng đôi khi bạn muốn cung cấp phiên bản đã lưu trong bộ nhớ cache cho đến khi tệp bị thay đổi. (với giải pháp trên, nó sẽ vô hiệu hóa hoàn toàn bộ nhớ cache cho hình ảnh đó) Vì vậy, để cung cấp hình ảnh được lưu trong bộ nhớ cache từ trình duyệt CHO ĐẾN KHI có sự thay đổi trong việc sử dụng tệp hình ảnh:
echo "<img src='/images/mychart.png?hash=" . filemtime('mychart.png') . "'>";
filemtime () lấy thời gian sửa đổi tệp.
Tôi biết chủ đề này đã cũ, nhưng nó xếp hạng rất tốt trong Google. Tôi phát hiện ra rằng việc đưa cái này vào tiêu đề của bạn hoạt động tốt;
<meta Http-Equiv="Cache-Control" Content="no-cache">
<meta Http-Equiv="Pragma" Content="no-cache">
<meta Http-Equiv="Expires" Content="0">
<meta Http-Equiv="Pragma-directive: no-cache">
<meta Http-Equiv="Cache-directive: no-cache">
Tôi chỉ đang tìm giải pháp cho vấn đề này và các câu trả lời ở trên không phù hợp với trường hợp của tôi (và tôi không đủ uy tín để bình luận về chúng). Nó chỉ ra rằng, ít nhất là đối với trường hợp sử dụng của tôi và trình duyệt tôi đang sử dụng (Chrome trên OSX), điều duy nhất dường như ngăn cản bộ nhớ đệm là:
Cache-Control = 'no-store'
Để hoàn thiện, tôi hiện đang sử dụng cả 3 'no-cache, no-store, must-revalidate'
Vì vậy, trong trường hợp của tôi (cung cấp hình ảnh được tạo động từ Flask bằng Python), tôi phải làm như sau để hy vọng hoạt động trong nhiều trình duyệt nhất có thể ...
def make_uncached_response(inFile):
response = make_response(inFile)
response.headers['Pragma-Directive'] = 'no-cache'
response.headers['Cache-Directive'] = 'no-cache'
response.headers['Cache-Control'] = 'no-cache, no-store, must-revalidate'
response.headers['Pragma'] = 'no-cache'
response.headers['Expires'] = '0'
return response
Thay đổi nguồn ảnh là giải pháp. Bạn thực sự có thể làm điều này bằng cách thêm dấu thời gian hoặc số ngẫu nhiên vào hình ảnh.
Tốt hơn là thêm một tổng kiểm tra ví dụ dữ liệu mà hình ảnh đại diện. Điều này cho phép bộ nhớ đệm khi có thể.
Hãy thêm một giải pháp khác vào nhóm.
Thêm một chuỗi duy nhất ở cuối là một giải pháp hoàn hảo.
example.jpg?646413154
Giải pháp sau mở rộng phương pháp này và cung cấp cả khả năng lưu vào bộ nhớ đệm và tìm nạp phiên bản mới khi hình ảnh được cập nhật.
Khi hình ảnh được cập nhật, thời gian tệp sẽ được thay đổi.
<?php
$filename = "path/to/images/example.jpg";
$filemtime = filemtime($filename);
?>
Bây giờ xuất hình ảnh:
<img src="images/example.jpg?<?php echo $filemtime; ?>" >
tôi đã gặp vấn đề này và khắc phục như thế này.
var newtags='<div class="addedimage"><h5>preview image</h5><img src="'+one+'?nocache='+Math.floor(Math.random() * 1000)+'"></div>';
Tôi đã sử dụng điều này để giải quyết vấn đề tương tự của mình ... hiển thị bộ đếm hình ảnh (từ nhà cung cấp bên ngoài). Nó không phải luôn làm mới một cách chính xác. Và sau khi một tham số ngẫu nhiên được thêm vào, tất cả đều hoạt động tốt :)
Tôi đã thêm một chuỗi ngày để đảm bảo làm mới ít nhất mỗi phút.
mã mẫu (PHP):
$output .= "<img src=\"http://xy.somecounter.com/?id=1234567890&".date(ymdHi)."\" alt=\"somecounter.com\" style=\"border:none;\">";
Điều đó dẫn đến một src
liên kết như:
http://xy.somecounter.com/?id=1234567890&1207241014
Nếu bạn có URL hình ảnh được mã hóa cứng, ví dụ: http://example.com/image.jpg bạn có thể sử dụng php để thêm tiêu đề vào hình ảnh của mình.
Đầu tiên, bạn sẽ phải thực hiện xử lý apache jpg của bạn dưới dạng php. Xem tại đây: Có thể thực thi PHP với phần mở rộng là file.php.jpg không?
Tải hình ảnh (imageecreatefromjpeg) từ tệp, sau đó thêm tiêu đề từ các câu trả lời trước đó. Sử dụng tiêu đề hàm php để thêm tiêu đề.
Sau đó xuất hình ảnh bằng hàm imagejpeg.
Xin lưu ý rằng rất không an toàn khi để php xử lý ảnh jpg. Ngoài ra, xin lưu ý rằng tôi chưa thử nghiệm giải pháp này nên tùy thuộc vào bạn để làm cho nó hoạt động.
Đơn giản, gửi một vị trí tiêu đề.
Trang web của tôi, chứa một hình ảnh và sau khi tải lên hình ảnh, không có gì thay đổi, sau đó tôi thêm mã này:
<?php header("Location: pagelocalimage.php"); ?>
Công việc là của tôi.