Ngăn bộ nhớ đệm iframe trong trình duyệt


86

Làm cách nào để ngăn Firefox và Safari lưu vào bộ nhớ đệm nội dung iframe?

Tôi có một trang web đơn giản với iframe đến một trang trên một trang khác. Cả trang bên ngoài và trang bên trong đều có tiêu đề phản hồi HTTP để ngăn chặn bộ nhớ đệm. Khi tôi nhấp vào nút "quay lại" trong trình duyệt, trang bên ngoài hoạt động bình thường, nhưng không có vấn đề gì, trình duyệt luôn truy xuất bộ nhớ cache của trang iframed. IE hoạt động tốt, nhưng Firefox và Safari đang khiến tôi gặp rắc rối.

Trang web của tôi trông giống như sau:

<html>
  <head><!-- stuff --></head>
<body>
  <!-- stuff -->
  <iframe src="webpage2.html?var=xxx" />
  <!-- stuff -->
</body>
</html>

Các varbiến luôn thay đổi. Mặc dù thực tế là URL của iframe đã thay đổi (và do đó, trình duyệt sẽ thực hiện một yêu cầu mới đối với trang đó), trình duyệt chỉ tìm nạp nội dung được lưu trong bộ nhớ cache.

Tôi đã kiểm tra các yêu cầu và phản hồi HTTP qua lại và tôi nhận thấy rằng ngay cả khi trang bên ngoài có chứa <iframe src="webpage2.html?var=222" />, trình duyệt vẫn sẽ tìm nạp webpage2.html?var=111.

Đây là những gì tôi đã thử cho đến nay:

  • Thay đổi URL iframe bằng giá trị var ngẫu nhiên
  • Thêm tiêu đề Expires, Cache-Control và Pragma vào trang web bên ngoài
  • Thêm tiêu đề Expires, Cache-Control và Pragma vào trang web bên trong

Tôi không thể thực hiện bất kỳ thủ thuật JavaScript nào vì tôi bị chính sách nguồn gốc chặn.

Tôi đang cạn kiệt ý tưởng. Có ai biết cách ngăn trình duyệt lưu vào bộ nhớ đệm nội dung iframed không?

Cập nhật

Tôi đã cài đặt Fiddler2 như Daniel đề xuất để thực hiện một thử nghiệm khác và thật không may, tôi vẫn nhận được kết quả tương tự.

Đây là bài kiểm tra tôi đã thực hiện:

  1. Trang bên ngoài tạo số ngẫu nhiên bằng cách sử dụng Math.random()trong JSP.
  2. Trang bên ngoài hiển thị số ngẫu nhiên trên trang web.
  3. Trang bên ngoài gọi iframe, chuyển số ngẫu nhiên.
  4. Trang bên trong hiển thị số ngẫu nhiên.

Với bài kiểm tra này, tôi có thể biết chính xác trang nào đang cập nhật và trang nào được lưu vào bộ nhớ đệm.

Kiểm tra thị giác

Để kiểm tra nhanh, tôi tải trang, điều hướng đến một trang khác, rồi nhấn "quay lại". Đây là kết quả:

Trang gốc:

  • Trang ngoài: 0,21300034290246206
  • Trang bên trong: 0,21300034290246206

Rời khỏi trang, sau đó nhấn lại:

  • Trang ngoài: 0.4470929019483644
  • Trang bên trong: 0,21300034290246206

Điều này cho thấy rằng trang bên trong đang được lưu vào bộ nhớ đệm, mặc dù trang bên ngoài đang gọi nó bằng một tham số GET khác trong URL. Vì một số lý do, trình duyệt đang bỏ qua thực tế rằng iframe đang yêu cầu một URL mới; nó chỉ cần tải cái cũ.

Kiểm tra Fiddler

Chắc chắn, Fiddler xác nhận điều tương tự.

(Tôi tải trang.)

Trang bên ngoài được gọi. HTML:

0.21300034290246206
<iframe src="http://ipv4.fiddler:1416/page1.aspx?var=0.21300034290246206" />

http: //ipv4.fiddler: 1416 / page1.aspx? var = 0.21300034290246206 được gọi.

(Tôi điều hướng khỏi trang và sau đó quay lại.)

Trang bên ngoài được gọi. HTML:

0.4470929019483644
<iframe src="http://ipv4.fiddler:1416/page1.aspx?var=0.4470929019483644" />

http: //ipv4.fiddler: 1416 / page1.aspx? var = 0.21300034290246206 được gọi.

Chà, từ thử nghiệm này, có vẻ như trình duyệt web không lưu vào bộ nhớ cache của trang, nhưng nó đang lưu vào bộ nhớ đệm URL của iframe và sau đó đưa ra yêu cầu mới trên URL được lưu trong bộ nhớ cache đó. Tuy nhiên, tôi vẫn lúng túng không biết làm thế nào để giải quyết vấn đề này.

Có ai có bất kỳ ý tưởng nào về cách ngăn trình duyệt web lưu vào bộ nhớ đệm các URL iframe không?


11
+1 - Bài viết của bạn ghi lại nỗi đau rất độc đáo.
nickf

1
Cảm ơn bạn đã giải thích rất chi tiết vấn đề, đây là chính xác 100% những gì tôi đang gặp phải với một trang web. Đã bảy năm và báo cáo lỗi firefox vẫn còn.
Scuzzy

Câu trả lời:


-3

Đặt URL của iframe trỏ đến một trang trên trang web của bạn, trang này hoạt động như một proxy để truy xuất và trả về nội dung thực của iframe. Bây giờ bạn không còn bị ràng buộc bởi chính sách cùng nguồn gốc (EDIT: không ngăn vấn đề bộ nhớ đệm iframe).


41
điều này không ngăn bộ nhớ cache.
baash05

@ baash05 Tôi chưa bao giờ tuyên bố nó đã làm; Tôi đã nói nó tránh chính sách cùng nguồn gốc.
kmoser

1
Đúng .. nhưng tiêu đề op có nội dung "Ngăn bộ nhớ đệm iframe trong trình duyệt" và nếu câu trả lời của bạn không ngăn bộ nhớ đệm iframe trong trình duyệt thì đó không thực sự là câu trả lời. Thật gọn gàng để biết, nhưng vẫn không phải là lời khuyên tốt cho những người đang tìm cách ngăn chặn bộ nhớ đệm.
baash05

OP đang tìm cách giải quyết bộ nhớ đệm tránh chính sách cùng nguồn gốc. Một phần câu trả lời tốt hơn là không có :)
kmoser

2
bánh mì nướng luôn rơi mứt xuống phía :)
baash05

58

Đây là một lỗi trong Firefox:

https://bugzilla.mozilla.org/show_bug.cgi?id=356558

Hãy thử cách giải quyết này:

<iframe src="webpage2.html?var=xxx" id="theframe"></iframe>

<script>
var _theframe = document.getElementById("theframe");
_theframe.contentWindow.location.href = _theframe.src;
</script>

3
Hôm nay 27.2.2014, tôi rất vui khi tìm thấy chủ đề này, tôi nghĩ rằng nó có thể được giải quyết bằng cách không có bộ nhớ đệm phía máy chủ. FF 27 vẫn có lỗi này.
Robert

7
7.8.2014 - 8 năm sau, và vẫn chưa được sửa.
Łukasz Zaroda

Điều này cũng áp dụng cho thuộc tính srcdoc, thật lạ ... Thật tuyệt vời khi tôi tìm thấy điều này.
elundmark

2
Tôi đã tìm thấy vấn đề bộ nhớ đệm tương tự này với Chrome và hai dòng JavaScript đã giải quyết nó. Cảm ơn bạn!
Thorn

2
Wow, có cùng một vấn đề. Dành riêng cho Firefox - hoạt động tốt trên IE, Chrome, v.v. Cảm ơn @caleb. Không thể tin rằng điều này đã kéo dài quá lâu.
Voodoo

32

Tôi đã có thể khắc phục lỗi này bằng cách đặt một namethuộc tính duy nhất trên iframe - vì bất kỳ lý do gì, điều này dường như làm hỏng bộ nhớ cache. Bạn có thể sử dụng bất kỳ dữ liệu động nào bạn có làm namethuộc tính - hoặc đơn giản là thời gian ms hoặc ns hiện tại bằng bất kỳ ngôn ngữ tạo mẫu nào bạn đang sử dụng. Đây là một giải pháp tốt hơn những giải pháp trên vì nó không yêu cầu trực tiếp JS.

Trong trường hợp cụ thể của tôi, iframe đang được xây dựng thông qua JS (nhưng bạn có thể làm tương tự qua PHP, Ruby, bất cứ điều gì), vì vậy tôi chỉ cần sử dụng Date.now():

return '<iframe src="' + src + '" name="' + Date.now() + '" />';

Điều này sửa lỗi trong thử nghiệm của tôi; có lẽ vì window.namecửa sổ bên trong thay đổi.


2
Câu trả lời này hoạt động cho Chrome, Firefox và Safari vào cuối năm 2015.
rovermicrover

13

Như bạn đã nói, vấn đề ở đây không phải là bộ nhớ đệm nội dung iframe mà là bộ nhớ đệm url của iframe .

Kể từ tháng 9 năm 2018, có vẻ như sự cố vẫn xảy ra trong Chrome nhưng không xảy ra trong Firefox.

Tôi đã thử nhiều cách (thêm thông số GET thay đổi, xóa url iframe trong onbeforeunload, phát hiện "tải lại từ bộ nhớ cache" bằng cách sử dụng cookie, thiết lập các tiêu đề phản hồi khác nhau) và đây là hai giải pháp duy nhất hoạt động với tôi:

1- Cách dễ dàng: tạo iframe của bạn động từ javascript

Ví dụ:

const iframe = document.createElement('iframe')
iframe.id = ...
...
iframe.src = myIFrameUrl 
document.body.appendChild(iframe)

2- Cách chuyển đổi

Phía máy chủ, như được giải thích ở đây , vô hiệu hóa bộ nhớ đệm nội dung cho nội dung bạn phân phối cho iframe HOẶC cho trang mẹ (sẽ làm được).

Đặt url iframe từ javascript với tham số tìm kiếm thay đổi bổ sung, như sau:

const url = myIFrameUrl + '?timestamp=' + new Date().getTime()
document.getElementById('my-iframe-id').src = url

(phiên bản đơn giản, hãy cẩn thận với các thông số tìm kiếm khác)


5

Sau khi thử mọi thứ khác (ngoại trừ sử dụng proxy cho nội dung iframe), tôi đã tìm ra cách để ngăn bộ nhớ đệm nội dung iframe từ cùng một miền :

Sử dụng .htaccessquy tắc ghi lại và thay đổi srcthuộc tính iframe .

RewriteRule test/([0-9]+)/([a-zA-Z0-9]+).html$ /test/index.php?idEntity=$1&token=$2 [QSA]

Cách tôi sử dụng là URL của iframe kết thúc theo hướng này: example.com/test/54/e3116491e90e05700880bf8b269a8cc7.html

Trong đó [mã thông báo] là giá trị được tạo ngẫu nhiên. URL này ngăn bộ nhớ đệm iframe vì mã thông báo không bao giờ giống nhau và iframe cho rằng đó là một trang web hoàn toàn khác vì một lần làm mới sẽ tải một URL hoàn toàn khác:

example.com/test/54/e3116491e90e05700880bf8b269a8cc7.html
example.com/test/54/d2cc21be7cdcb5a1f989272706de1913.html

cả hai đều dẫn đến cùng một trang.

Bạn có thể truy cập các thông số url ẩn của mình bằng $_SERVER["QUERY_STRING"]


1
Đã làm việc cho tôi - Cảm ơn!
Quinn Finney

@QuinnFinney Rất vui vì điều này hữu ích với người khác. Tôi mất vài ngày để giải quyết vấn đề này :)
Jeff Noel

Ừ - tôi cũng vậy! hahaha
Quinn Finney


3

Để iframe luôn tải nội dung mới, hãy thêm dấu thời gian Unix hiện tại vào cuối thông số GET. Sau đó, trình duyệt coi đó là một yêu cầu 'khác' và sẽ tìm kiếm nội dung mới.

Trong Javascript, nó có thể giống như sau:

frames['my_iframe'].location.href='load_iframe_content.php?group_ID=' + group_ID + '&timestamp=' + timestamp;

3

Tôi đã tìm thấy sự cố này trong Chrome mới nhất cũng như Safari mới nhất trên Mac OS X kể từ ngày 17 tháng 3 năm 2016. Không có bản sửa lỗi nào ở trên phù hợp với tôi, bao gồm việc gán src để trống rồi quay lại một số trang web hoặc thêm vào một số tham số "name" được đặt tên ngẫu nhiên hoặc thêm một số ngẫu nhiên vào cuối URL sau hàm băm, hoặc gán cửa sổ nội dung href cho src sau khi gán src.

Trong trường hợp của tôi, đó là do tôi đang sử dụng Javascript để cập nhật IFRAME và chỉ chuyển đổi hàm băm trong URL.

Cách giải quyết trong trường hợp của tôi là tôi đã tạo một URL tạm thời có chuyển hướng meta 0 giây đến trang khác đó. Nó xảy ra quá nhanh nên tôi hầu như không nhận thấy màn hình nhấp nháy. Thêm vào đó, tôi đã làm cho màu nền của trang tạm thời giống với màu của trang kia, và vì vậy bạn thậm chí còn nhận thấy nó ít hơn.


2

Tôi đặt thuộc tính src iframe sau trong ứng dụng của mình. Để loại bỏ nội dung được lưu trong bộ nhớ cache bên trong iframe khi bắt đầu ứng dụng, tôi chỉ cần thực hiện:

myIframe.src = "";

... ở đâu đó ở đầu mã js (ví dụ: trong trình xử lý jquery $ ())

Cảm ơn http://www.freshsupercool.com/2008/07/10/firefox-caching-iframe-data/


0

Tôi cũng gặp sự cố này vào năm 2016 với iOS Safari. Điều dường như hiệu quả với tôi là cung cấp tham số GET cho iframe src và một giá trị cho nó như thế này

<iframe width="60%" src="../other/url?cachebust=1" allowfullscreen></iframe>


-1

Bạn đã cài đặt Fiddler2 chưa?

Nó sẽ cho bạn biết chính xác những gì đang được yêu cầu, những gì đang được gửi lại, v.v. Nghe có vẻ không hợp lý khi trình duyệt thực sự nhấn vào bộ nhớ cache của nó cho các URL khác nhau.


1
Cảm ơn vì mẹo trên Fiddler2. Bây giờ tôi biết rằng trình duyệt không lưu nội dung iframe vào bộ nhớ đệm; nó chỉ đơn giản là lưu vào bộ nhớ đệm URL iframe. Tuy nhiên, tôi vẫn bối rối và không hiểu tại sao trình duyệt lại bỏ qua URL iframe của trang mới và chỉ sử dụng URL cũ.
JR.

-1

Nếu bạn muốn thực sự điên rồ, bạn có thể triển khai tên trang dưới dạng url động luôn phân giải đến cùng một trang, thay vì tùy chọn chuỗi truy vấn?

Giả sử bạn đang ở trong văn phòng, hãy kiểm tra xem có bất kỳ bộ nhớ đệm nào đang diễn ra ở cấp độ mạng hay không. Tin tôi đi, đó là một khả năng. Nhân viên CNTT của bạn sẽ có thể cho bạn biết nếu có bất kỳ cơ sở hạ tầng mạng nào xung quanh bộ nhớ đệm HTTP, mặc dù điều này chỉ xảy ra đối với iframe nên khó xảy ra.


-2

Bạn đã thử thêm các tùy chọn HTTP Header khác nhau để không có bộ nhớ cache vào trang iframe chưa?


Đúng vậy. Tôi đã thử các lệnh no-cache trong cả tiêu đề HTTP và thẻ meta trên mỗi trang.
JR.
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.