2009-07-28 33 views
105

Nếu javascript sửa đổi DOM trong trang A, người dùng điều hướng đến trang B và sau đó nhấn nút quay lại để quay lại trang A. Tất cả sửa đổi đối với DOM của trang A bị mất và người dùng được trình bày phiên bản ban đầu được truy xuất từ ​​máy chủ.Ajax, nút quay lại và cập nhật DOM

Nó hoạt động theo cách đó trên stackoverflow, reddit và nhiều trang web phổ biến khác. (cố gắng thêm nhận xét thử nghiệm cho câu hỏi này, sau đó điều hướng đến trang khác và nhấn nút quay lại để quay lại - nhận xét của bạn sẽ "biến mất")

Điều này có ý nghĩa nhưng một số trang web (apple.com, basecamphq.com vv) bằng cách nào đó buộc trình duyệt phải phục vụ người dùng trạng thái mới nhất của trang. (truy cập http://www.apple.com/ca/search/?q=ipod, nhấp vào liên kết Tải xuống ở trên cùng và sau đó nhấp vào nút quay lại - tất cả cập nhật DOM sẽ được giữ nguyên)

sự không nhất quán đến từ đâu?

+0

Điều thú vị là Apple đang ghi nhớ trạng thái mà không sửa đổi băm. Hmmm – James

+0

Apple trông giống như họ đang thao tác phản hồi bộ nhớ đệm – BigBlondeViking

+0

Như những người khác đã đề xuất điều này không liên quan đến javascript hoặc ajax. Bạn nên xóa các thẻ đó để có câu trả lời đúng. – BYK

Trả lời

102

Một câu trả lời: Trong số những thứ khác, sự kiện dỡ tải khiến bộ nhớ cache lùi/chuyển tiếp bị vô hiệu.

Một số trình duyệt lưu trữ trạng thái hiện tại của toàn bộ trang web trong cái gọi là "bfcache" hoặc "bộ nhớ cache trang". Điều này cho phép họ kết xuất lại trang rất nhanh khi điều hướng qua các nút quay lại và tiến lên, đồng thời duy trì trạng thái của DOM và tất cả các biến JavaScript. Tuy nhiên, khi một trang chứa các sự kiện onunload, các sự kiện đó có thể đưa trang đó vào trạng thái không hoạt động, và vì vậy trang không được lưu trữ trong bfcache và phải được tải lại (nhưng có thể được nạp từ bộ nhớ cache chuẩn) và kết xuất từ ​​đầu, bao gồm chạy tất cả các trình xử lý tải. Khi trở về một trang thông qua bfcache, DOM được giữ trong trạng thái trước đó của nó, mà không cần phải kích hoạt các trình xử lý tải (vì trang đã được tải).

Lưu ý rằng hành vi của bfcache khác với bộ nhớ cache của trình duyệt chuẩn liên quan đến Cache-Control và các tiêu đề HTTP khác. Trong nhiều trường hợp, các trình duyệt sẽ cache một trang trong bfcache ngay cả khi nó không lưu trữ nó trong bộ nhớ cache chuẩn.

jQuery tự động đính kèm sự kiện dỡ hàng vào cửa sổ, vì vậy rất tiếc khi sử dụng jQuery sẽ loại trang của bạn không được lưu trữ trong bfcache để bảo quản DOM và nhanh chóng quay lại/chuyển tiếp. [Cập nhật: điều này đã được cố định trong jQuery 1.4 để nó chỉ áp dụng cho IE]

+3

bạn hoàn toàn đóng đinh nó. cả hai, reddit và stackoverflow đang sử dụng jquery trong khi basecamp và apple đang sử dụng prototypejs. điều này khá nhiều giải thích tất cả mọi thứ. –

+0

+1 thú vị (không qua trình duyệt mặc dù) câu hỏi khác xa so với khi nó bắt đầu ... – BigBlondeViking

+1

nó có thể là trình duyệt chéo vì tôi có thể tái tạo nó trên Internet Explorer của tôi.Tôi chắc chắn rằng mỗi webbrowser với javascript kích hoạt đã phải đối phó với vấn đề này anyway. nhưng điều này thực sự là một mớ hỗn độn, khi bạn nghĩ về điều đó, nút quay lại sẽ luôn đưa mọi người đến trang mà họ đã nhìn thấy lần cuối với tất cả cập nhật DOM, nhà phát triển javascript, v.v. không nên phá vỡ điều này bằng cách làm điều gì đó trong sự kiện dỡ hàng và nếu họ làm, webbrowsers không nên cố gắng sửa chữa vấn đề bằng cách không sử dụng bfcache cả. toàn bộ sự kiện dỡ hàng là một trò đùa lớn. Tôi chắc chắn 99% thời gian nó được sử dụng để vá lỗi rò rỉ bộ nhớ. –

0

Điều bạn đang tìm kiếm là dành cho một số loại quản lý băm URL. Số # trong url chỉ dành cho phía máy khách.

Khi bạn thay đổi trạng thái của mặt sau bằng JS, khi đó bạn cập nhật dữ liệu trong # của url.

Ngoài ra, bạn thêm một số loại bỏ phiếu theo dõi nếu băm đã thay đổi và tải trạng thái của trang dựa trên dữ liệu mới trong băm.

Hãy xem này:

http://ajaxpatterns.org/Unique_URLs

+3

điều này không liên quan gì đến biểu tượng băm. –

+3

Bạn sai, anh ấy đang tìm cách phổ biến nhất để bảo toàn trạng thái trang trong một giải pháp AJAX. – BigBlondeViking

3

Facebook nhớ trạng thái trang bằng cách thay đổi nhận dạng băm trong URL cho các yêu cầu ajax. Những thay đổi này được ghi lại trong lịch sử trình duyệt, vì vậy khi người dùng nhấp vào nút quay lại, hàm băm sẽ thay đổi thành những gì trước đây. Vì vậy, sau đó nó được ngụ ý rằng bạn sẽ cần một số Javascript để theo dõi các định danh có và phản ứng khi nó được thay đổi bởi trình duyệt. Andreas Blixt has a hash monitoring script available.

+0

vào ngày hôm nay nó không làm như vậy có thể cho tôi biết những gì facebook hiện nay –

2

Sử dụng trình nhận dạng băm/đoạn URL là một cách khá phổ biến để móc/ghi nhớ trạng thái trong ứng dụng web dựa trên các bản cập nhật Ajax và DOM.

Kiểm tra dự án Really Simple History để biết một số ý tưởng. Có thể theo dõi URL để thay đổi giá trị băm và rsh thực hiện điều này, có tính đến sự khác biệt của trình duyệt.

3

Điều này không liên quan gì đến biểu tượng băm (#).

Nếu bạn kiểm tra tiêu đề HTTP của apple, nó chỉ đơn giản là lưu vào bộ nhớ cache của trang.

+0

Apple ví dụ là người nghèo, họ không "tiết kiệm" trang nhà nước, giả định của mình DOM được bảo quản nó sai – BigBlondeViking

+2

Bạn có biết cập nhật DOM là gì không? Đó là những gì anh ta hỏi. –

+0

Bạn không hiểu. –

12

Tôi đã cố gắng để có được Chrome để hành xử như Safari không, và cách duy nhất tôi đã tìm thấy rằng làm việc là để thiết lập Cache-control: no-store trong tiêu đề. Điều này buộc trình duyệt tìm nạp lại trang từ máy chủ khi người dùng nhấn nút quay lại. Không lý tưởng, nhưng tốt hơn là được hiển thị một trang lỗi thời.

+3

Đây là câu trả lời đúng cho bản gốc câu hỏi. Nếu bạn muốn bắt buộc tải lại máy chủ trên nút quay lại, hãy sử dụng điều khiển bộ nhớ cache 'không lưu trữ, không có bộ nhớ cache, phải xác thực lại'. Chrome không muốn lưu trữ và IE muốn phải xác thực lại. Đối với các trình duyệt khác (và w3c) no-cache là đủ. – woens

1

Đối với bất kỳ ai đang gặp sự cố với Rails và điều này - vấn đề của bạn không phải là bfcache (tôi nghĩ là vậy) - đó là đá quý turbolinks. Here là cách xóa nó.

Hy vọng rằng điều này sẽ giúp bạn tiết kiệm thời gian và đập đầu vào tường.

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