2012-06-28 31 views
9

Để cải thiện hiệu suất/đáp ứng của trang web của tôi, tôi đã thực hiện tải trang một phần bằng AJAX, replaceState, pushState và trình nghe popstate.Nút quay lại API lịch sử HTML5 với tải trang một phần

Tôi về cơ bản lưu phần trung tâm của trang (HTML) làm đối tượng trạng thái của tôi trong lịch sử. Khi một liên kết được nhấp, tôi chỉ yêu cầu bit trung tâm của trang từ máy chủ (xác định các yêu cầu này với một tiêu đề Chấp nhận khác) và thay thế bằng javascript. Trên popstate tôi lấy phần trung tâm trước đó và đẩy nó trở lại vào dom.

Điều này chủ yếu hoạt động tốt, tuy nhiên tôi đã tìm thấy một vấn đề cụ thể mà tôi đang gặp phải. Đó là một chút phức tạp để giải thích, vì vậy xin lỗi của tôi nếu điều này không phải là rất rõ ràng.

Có một hình thức tìm kiếm trên hầu hết các trang của chúng tôi. Việc tải trang một phần thông qua ajax chỉ trên các yêu cầu GET và biểu mẫu thực hiện một POST dẫn đến tải trang đầy đủ.

Nếu tôi di chuyển các thiết lập trang sau, tôi kết thúc trên một trang một phần bị thay đổi bao gồm CHỈ nội dung trung tâm, mà không cần bất kỳ dom xung quanh:

Start trên Trang chủ (thông qua trang đầy đủ tải) - thực hiện Tìm kiếm (sau chuyển hướng-nhận)
Đưa bạn đến Kết quả Tìm kiếm (thông qua tải trang đầy đủ) - sau đó nhấp vào Trang chủ
Trả lại bạn về Trang chủ (qua nhận động) - nhấp vào trình duyệt quay lại
Tìm kiếm Kết quả (từ người nghe popstate) - nhấp vào trình duyệt quay lại
Trang chủ không đúng định dạng e.

Khi trang chủ không đúng định dạng xuất hiện, người nghe popstate của tôi không có mặt.

Điều tôi nghĩ rằng đang xảy ra, là tải thứ hai (động, một phần trả lời thay vì trang đầy đủ.

Để cố gắng khắc phục điều này, tôi đã thêm tiêu đề Vary: Accept vào phản hồi để cho trình duyệt biết rằng nội dung có thể thay đổi dựa trên tiêu đề chấp nhận. Tôi cũng đã thêm Cache-Control max-age = 0, pragma no-cache và ngày hết hạn trong quá khứ cho nội dung được tải một phần để cố gắng buộc trình duyệt không lưu vào bộ nhớ cache này, nhưng không có cách nào giải quyết được.

Rất tiếc, công ty của tôi không cho phép lưu lượng truy cập bên ngoài vào máy chủ dev của chúng tôi, vì vậy tôi không thể cho bạn thấy sự cố. Tôi đã xem xét các câu hỏi tương tự khác nhau ở đây, nhưng không có câu hỏi nào trong số họ có vẻ giống nhau, cũng như các giải pháp được đề xuất dường như không hoạt động.

Nếu tôi thêm một tham số vô nghĩa (blah = blah) vào các yêu cầu GET động của tôi, điều này sẽ giải quyết được vấn đề. Tuy nhiên đây là một hack xấu xí mà tôi không muốn làm. Điều này có vẻ như nó nên được giải quyết với các tiêu đề, vì tôi nghĩ rằng đó là một vấn đề bộ nhớ đệm. Bất cứ ai có thể giải thích những gì đang xảy ra?

+0

Cập nhật nhanh - tiêu đề dường như giải quyết được sự cố trên Firefox, tuy nhiên nó vẫn tồn tại trên Chrome và iOS Safari (có thể là do webkit?) –

+0

Nghe có vẻ giống như vấn đề bộ nhớ đệm. Việc thêm tham số vào các yêu cầu GET động có vẻ hợp lý - đó là những gì jquery-pjax thực hiện. –

Trả lời

8

Đó là sự cố bộ nhớ cache. Với tiêu đề phản hồi Cache-Control được đặt thành no-cache hoặc max-age=0, sự cố không xảy ra trong FF (như bạn đã nói), nhưng vẫn tồn tại trong Chrome.

Tiêu đề làm việc cho tôi là Cache-Control: no-store. Điều đó không được thực hiện một cách nhất quán bởi tất cả các trình duyệt (bạn có thể tìm câu hỏi về sự khác biệt giữa không có bộ nhớ cache và không lưu trữ), nhưng cũng có kết quả mà bạn mong đợi trong Chrome.

1

Tôi gặp sự cố tương tự. Tôi đang xây dựng một thuật sĩ dựa trên web và sử dụng jquery ajax để tải từng bước (ASP.NET MVC ở mặt sau).

Tuyến đường nội tạng giống như/Câu hỏi/Hiển thị - tải toàn bộ trang và hiển thị câu hỏi đầu tiên (câu hỏi 0). Khi người dùng nhấp vào hình ảnh Tiếp theo, nó thực hiện một jquery .load() với url/Questions/Save/0. Điều này sẽ tiết kiệm câu trả lời và trả về một phần xem với câu hỏi tiếp theo. Lần lưu tiếp theo thực hiện lệnh jquery .load() với/Questions/Save/1 ...

Tôi đã triển khai History.js để người dùng có thể quay lại và chuyển tiếp (ra?). Nó lưu trữ số câu hỏi trong dữ liệu trạng thái. Khi nó phát hiện một statechange (và số câu hỏi của nhà nước là khác nhau từ những gì trên trang), nó có một jquery .load() để tải câu hỏi chính xác.

Lúc đầu, tôi đã sử dụng cùng một tuyến đường như khi trang ban đầu được tải (/ Câu hỏi/Hiển thị/X trong đó X là số câu hỏi). Ở mặt sau, tôi phát hiện xem đó có phải là yêu cầu ajax hay không, và nếu như vậy trả lại một phần xem thay vì xem toàn bộ. Đây là nơi vấn đề đến tương tự như của bạn: Giả sử tôi đã đặt câu hỏi 3, quay lại, sau đó chuyển tiếp, sau đó truy cập www.google.com.vn và sau đó nhấn nút quay lại. Nó cho thấy câu hỏi 3 nhưng nó là một phần xem - bởi vì trình duyệt lưu trữ một phần cho tuyến đường đó.

Giải pháp của tôi là tạo một tuyến đường riêng cho cuộc gọi ajax:/Questions/Load/X (sử dụng mã thông thường ở đầu sau). Bây giờ với hai tuyến đường khác nhau (/ Câu hỏi/Hiển thị cho non-ajax và/Questions/Load cho ajax), trình duyệt hiển thị toàn bộ trang chính xác trong tình huống trên.

Vì vậy, có thể một giải pháp tương tự sẽ phù hợp với bạn ... tức là hai tuyến đường khác nhau cho trang chủ của bạn - một cho toàn bộ trang và một cho một phần. Hy vọng rằng sẽ giúp.

0

Khi một liên kết được nhấp tôi yêu cầu chỉ là chút trung tâm của trang từ máy chủ (xác định những yêu cầu này với một khác nhau Chấp nhận tiêu đề) và thay thế bằng javascript.

Tuyệt vời. Đó là cách RESTful để làm điều đó. Nhưng có một điều cần làm để làm cho nó hoạt động: thêm một tiêu đề Vary vào phản hồi.

Vary: Accept 

Điều đó cho trình duyệt biết rằng yêu cầu có tiêu đề Chấp nhận khác có thể nhận được phản hồi khác. Do hai yêu cầu sử dụng các tiêu đề Chấp nhận khác nhau, trình duyệt (và mọi proxy lưu trữ) sẽ lưu trữ riêng các câu trả lời.

Không giống như thiết lập Cache-Control: no-store, điều này sẽ vẫn cho phép bạn sử dụng bộ nhớ đệm.

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