Sửa đổi URL thanh địa chỉ trong ứng dụng AJAX để khớp với trạng thái hiện tại


166

Tôi đang viết một ứng dụng AJAX, nhưng khi người dùng di chuyển qua ứng dụng, tôi muốn URL trong thanh địa chỉ để cập nhật mặc dù thiếu tải lại trang. Về cơ bản, tôi muốn họ có thể đánh dấu bất cứ lúc nào và từ đó trở về trạng thái hiện tại.

Mọi người xử lý việc duy trì RESTfulness trong các ứng dụng AJAX như thế nào?


2
Nó được sử dụng để kiểm tra trạng thái ứng dụng của bạn, nhưng không liên quan gì đến "RESTfulness".
Mohamed

29
window.history.pushState(null,'hi','page1?id=32')
Omu

3
câu trả lời được chấp nhận đã được viết cách đây 5 năm và trong khi đó, chúng tôi đã nhận được window.history.pushState, giống như @Omu nói. location.hash mang lại nhiều vấn đề và tốt nhất là tránh nó.
pcarvalho

Tôi đã chỉnh sửa câu trả lời để làm cho cách tiếp cận PushState nổi bật.
jasonjwwilliams

Câu trả lời:


116

Cách để thực hiện việc này là thao tác location.hashkhi cập nhật AJAX dẫn đến thay đổi trạng thái mà bạn muốn có một URL riêng biệt. Ví dụ: nếu url của trang của bạn là:

http://example.com/

Nếu một chức năng phía máy khách thực thi mã này:

// AJAX code to display the "foo" state goes here.

location.hash = 'foo';

Sau đó, URL được hiển thị trong trình duyệt sẽ được cập nhật thành:

http://example.com/#foo

Điều này cho phép người dùng đánh dấu trạng thái "foo" của trang và sử dụng lịch sử trình duyệt để điều hướng giữa các trạng thái.

Khi có cơ chế này, bạn sẽ cần phân tích phần băm của URL ở phía máy khách bằng cách sử dụng JavaScript để tạo và hiển thị trạng thái ban đầu thích hợp, vì các số nhận dạng phân đoạn (phần sau #) không được gửi đến người phục vụ.

Plugin hashchange của Ben Alman giúp người dùng dễ dàng sử dụng jQuery.


Có vẻ như bạn đúng. Đó là cách tiếp cận duy nhất. Đây có vẻ như là một lời giải thích chi tiết về lời khuyên của bạn: < ajaxpotypes.org/Unique_URLs >
jasonjwwilliams

@buymeasoda Cảm ơn bạn đã chỉnh sửa; Tôi không chắc mình đã nghĩ gì khi viết phần đó.
Dave Ward

1
Wow, câu trả lời này rất hữu ích. Mặc dù các ví dụ URL hơi khó hiểu, SO có thể tự động thay thế các liên kết bằng tiêu đề. Làm thế nào về việc thay thế những thứ đó bằng một cái gì đó như example.com và example.com/#foo, để chúng ta có thể thấy toàn bộ url trong bản rõ.
Neil

4
@Pascal Bạn có thể, nhưng chỉ trong các trình duyệt hỗ trợ PushState của HTML5. Thông tin tốt về điều đó tại đây: diveintohtml5.info/history.html
Dave Ward

1
Cuối

18

Nhìn vào các trang web như book.cakephp.org. Trang web này thay đổi URL mà không cần sử dụng hàm băm và sử dụng AJAX. Tôi không chắc nó làm thế nào chính xác nhưng tôi đã cố gắng tìm ra nó. Nếu ai biết, hãy cho tôi biết.

Ngoài ra github.com khi xem xét điều hướng trong một dự án nhất định.


Tôi nhận thấy rằng với GitHub một tuần trước đây. Làm thế nào trên trái đất họ làm điều đó? Phải quay lại và kiểm tra.
vẽ Noakes

16
Họ dường như đang sử dụng hàm javascript PushState (). Điều này thêm vào lịch sử trình duyệt của bạn. Nhìn vào nó; nó khá thú vị và tuyệt vời
daniel.wright

Cảm ơn vì điều này, nó chính xác là những gì tôi đang tìm kiếm. Tôi đã tự hỏi làm thế nào github đã làm điều đó. Lúc đầu tôi nghĩ nó phải tải lại nhưng chỉ có yêu cầu AJAX. Trong Opera, nó đã tải lại trang.
kamranicus

Kỹ thuật tương tự được sử dụng bởi fb trong khi điều hướng qua các trang của các nhóm khác nhau. Bạn có một cột điều hướng bên trái trong đó các nhóm khác nhau được đề cập. Khi bạn nhấp vào một tên nhóm cụ thể, url sẽ thay đổi và chỉ nội dung của khung nội dung chính thay đổi cùng với url (không có hàm băm). Vì vậy, khi người dùng tải lại trang, họ không được chuyển hướng đến trang chủ mà đến trang của các nhóm.
Madeyedexter

17

Người viết không muốn tải lại hoặc chuyển hướng khách truy cập của mình khi sử dụng Ajax. Nhưng tại sao không sử dụng HTML5 pushState/ replaceState?

Bạn sẽ có thể sửa đổi thanh địa chỉ bao nhiêu tùy thích. Nhận các url tìm kiếm tự nhiên, với AJAX.

Kiểm tra mã trên dự án mới nhất của tôi: http://iesus.se/


11

Điều này tương tự như những gì Kevin nói. Bạn có thể có trạng thái máy khách của mình dưới dạng một số đối tượng javascript và khi bạn muốn lưu trạng thái, bạn tuần tự hóa đối tượng (sử dụng mã hóa JSON và base64). Sau đó, bạn có thể đặt đoạn của href thành chuỗi này.

var encodedState = base64(json(state));
var newLocation = oldLocationWithoutFragment + "#" + encodedState;

document.location = newLocation; // adds new entry in browser history
document.location.replace(newLocation); // replaces current entry in browser history

Cách đầu tiên sẽ coi trạng thái mới là vị trí mới (vì vậy nút quay lại sẽ đưa chúng đến vị trí trước đó). Cái sau thì không.


Có cách nào để thêm một mục vào lịch sử đánh dấu mà không làm mới trang không? Đặt vị trí (như trong ví dụ đầu tiên của bạn) sẽ làm mới, phải không?
Drew Noakes

làm document.location.replace cũng sẽ chuyển hướng trình duyệt đến url đó (chỉ cần thử nó trong bảng điều khiển chrome)
Omu

3

SWFAddress hoạt động trong các dự án Flash & Javascript và cho phép bạn tạo các URL có thể đánh dấu (sử dụng phương pháp băm được đề cập ở trên) cũng như cung cấp cho bạn hỗ trợ nút quay lại.

http://www.asual.com/swfaddress/


3

Phương thức window.location.hash là cách làm việc ưa thích. Để giải thích về cách thực hiện, Mô hình Ajax - URL duy nhất .

YUI có triển khai mẫu này dưới dạng một mô-đun, bao gồm các công việc cụ thể của IE xung quanh để có được nút quay lại hoạt động cùng với việc viết lại địa chỉ bằng cách sử dụng hàm băm. Trình quản lý lịch sử trình duyệt YUI .

Các khung khác có triển khai tương tự là tốt. Điểm quan trọng là nếu bạn muốn lịch sử hoạt động cùng với việc viết lại địa chỉ, các trình duyệt khác nhau cần các cách xử lý khác nhau. (Điều này được chi tiết trong bài viết liên kết đầu tiên.)

IE cần một hack dựa trên iframe, trong đó Firefox sẽ tạo lịch sử kép bằng cùng một phương thức.


3

Nếu OP hoặc những người khác vẫn đang tìm cách sửa đổi lịch sử trình duyệt để kích hoạt trạng thái, sử dụng PushState và thay thếState, như đề xuất của IESUS, là cách 'đúng' để thực hiện ngay bây giờ. Đó là lợi thế chính so với location.hash dường như là nó tạo ra các url thực sự, không chỉ là băm. Nếu lịch sử trình duyệt sử dụng băm được lưu, và sau đó xem lại với javascript bị vô hiệu hóa, ứng dụng sẽ không hoạt động, vì băm không được gửi đến máy chủ. Tuy nhiên, nếu PushState đã được sử dụng, toàn bộ tuyến đường sẽ được gửi đến máy chủ, sau đó bạn có thể xây dựng để đáp ứng một cách thích hợp các tuyến đường. Tôi đã thấy một ví dụ trong đó các mẫu ria mép giống nhau được sử dụng trên cả máy chủ và phía máy khách. Nếu ứng dụng khách đã bật javascript, anh ta sẽ nhận được phản hồi linh hoạt bằng cách tránh làm tròn số đến máy chủ, nhưng ứng dụng sẽ hoạt động hoàn toàn tốt nếu không có javascript. Do đó, ứng dụng có thể xuống cấp một cách duyên dáng trong trường hợp không có javascript.

Ngoài ra, tôi tin rằng có một số khung công tác ngoài kia, với một tên như history.js. Đối với các trình duyệt hỗ trợ HTML5, nó sử dụng PushState, nhưng nếu trình duyệt không hỗ trợ điều đó, nó sẽ tự động quay trở lại sử dụng băm.


2

Kiểm tra xem người dùng có ở trong trang hay không, khi bạn nhấp vào thanh url, javascript cho biết bạn đã hết trang. Nếu bạn thay đổi thanh url và nhấn 'ENTER' với ký hiệu '#' trong đó thì bạn vào lại trang, không cần nhấp vào trang bằng tay với con trỏ chuột, sau đó một lệnh sự kiện keyboad (document.onkeypress) từ javascript sẽ có thể kiểm tra xem nó có nhập và kích hoạt javascript để chuyển hướng không. Bạn có thể kiểm tra xem người dùng có VÀO trang với window.onf Focus hay không và kiểm tra xem anh ta có ra với window.onblur không.

Vâng, nó có thể.

;)


Đây là cách tôi thấy thanh lịch để thay đổi trang khi người dùng chỉnh sửa thanh url bằng ký hiệu #.
Marcelo
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.