Ubah URL Bilah Alamat di Aplikasi AJAX agar Sesuai dengan Kondisi Saat Ini

166

Saya sedang menulis aplikasi AJAX, tetapi ketika pengguna bergerak melalui aplikasi, saya ingin URL di bilah alamat diperbarui meskipun kurangnya reload halaman. Pada dasarnya, saya ingin mereka dapat melakukan bookmark kapan saja dan dengan demikian kembali ke keadaan saat ini.

Bagaimana orang-orang menangani pemeliharaan RESTfulness di aplikasi AJAX?

jasonjwwilliams
sumber
2
Ini digunakan untuk mempertahankan kondisi aplikasi Anda, tetapi tidak ada hubungannya dengan "RESTfulness".
Mohamed
29
window.history.pushState(null,'hi','page1?id=32')
Omu
3
jawaban yang diterima ditulis 5 tahun yang lalu dan sementara itu, kami mendapat window.history.pushState, seperti yang dikatakan @Omu. location.hash membawa banyak masalah dan yang terbaik untuk menghindarinya.
pcarvalho
Saya telah mengedit jawaban untuk membuat pendekatan pushState menonjol.
jasonjwwilliams

Jawaban:

116

Cara untuk melakukan ini adalah dengan memanipulasi location.hashketika pembaruan AJAX menghasilkan perubahan status yang Anda ingin memiliki URL diskrit. Misalnya, jika url halaman Anda adalah:

http://example.com/

Jika fungsi sisi klien mengeksekusi kode ini:

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

location.hash = 'foo';

Kemudian, URL yang ditampilkan di browser akan diperbarui ke:

http://example.com/#foo

Ini memungkinkan pengguna untuk menandai kondisi "foo" halaman, dan menggunakan riwayat browser untuk bernavigasi di antara negara.

Dengan adanya mekanisme ini, Anda harus mem-parsing bagian hash dari URL di sisi klien menggunakan JavaScript untuk membuat dan menampilkan keadaan awal yang sesuai, karena pengidentifikasi fragmen (bagian setelah #) tidak dikirim ke server.

Plugin hashchange Ben Alman membuat yang terakhir sangat mudah jika Anda menggunakan jQuery.

Dave Ward
sumber
Sepertinya kamu benar. Itu satu-satunya pendekatan. Ini sepertinya penjelasan terperinci yang bagus tentang saran Anda: < ajaxpatterns.org/Unique_URLs >
jasonjwwilliams
@buymeasoda Terima kasih atas hasil editnya; Saya tidak yakin apa yang saya pikirkan ketika saya menulis bagian itu.
Dave Ward
1
Wow, jawaban ini sangat membantu. Meskipun contoh URL agak membingungkan, SO mungkin secara otomatis mengganti tautan dengan judul. Bagaimana kalau mengganti mereka dengan sesuatu seperti example.com dan example.com/#foo, sehingga kita bisa melihat seluruh url di plaintext.
Neil
4
@ Pascal Anda bisa, tetapi hanya di browser yang mendukung pushState HTML5. Info bagus tentang itu di sini: diveintohtml5.info/history.html
Dave Ward
1
Saya akhirnya menjadi penggemar berat history.js untuk membahas dasar-dasar kompatibilitas browser github.com/andreasbernhard/history.js
jocull
18

Lihatlah situs-situs seperti book.cakephp.org. Situs ini mengubah URL tanpa menggunakan hash dan menggunakan AJAX. Saya tidak yakin bagaimana melakukannya dengan tepat, tetapi saya sudah berusaha mencari tahu. Jika ada yang tahu, beri tahu saya.

Juga github.com saat melihat navigasi dalam proyek tertentu.

daniel.wright
sumber
Saya perhatikan itu dengan GitHub sekitar seminggu yang lalu. Bagaimana mereka melakukan itu? Harus kembali dan periksa.
Drew Noakes
16
Mereka tampaknya menggunakan fungsi javascript pushState (). Ini menambah riwayat browser Anda. Lihatlah ke dalamnya; ini sangat menarik dan keren.
daniel.wright
Terima kasih untuk ini, tepat seperti yang saya cari. Saya bertanya-tanya bagaimana github melakukannya. Pada awalnya saya pikir itu harus memuat ulang tetapi hanya ada permintaan AJAX. Di Opera, itu memuat ulang halaman.
kamranicus
Teknik serupa digunakan oleh fb saat menavigasi halaman-halaman kelompok yang berbeda. Anda memiliki kolom nav kiri di mana grup yang berbeda disebutkan. Ketika Anda mengklik pada nama grup tertentu url berubah dan hanya konten panel konten utama yang berubah bersama dengan url (tidak ada hash). Jadi, ketika pengguna memuat ulang halaman mereka tidak diarahkan ke halaman rumah tetapi ke halaman grup.
Madeyedexter
17

Tidak mungkin penulis ingin memuat ulang atau mengarahkan ulang pengunjungnya ketika menggunakan Ajax. Tapi mengapa tidak menggunakan HTML5's pushState/ replaceState?

Anda dapat memodifikasi bilah alamat sebanyak yang Anda suka. Dapatkan url yang terlihat alami, dengan AJAX.

Lihat kode pada proyek terbaru saya: http://iesus.se/

iesus
sumber
11

Ini mirip dengan apa yang dikatakan Kevin. Anda dapat memiliki negara klien Anda sebagai beberapa objek javascript, dan ketika Anda ingin menyimpan negara, Anda membuat serial objek (menggunakan JSON dan base64 encoding). Anda kemudian dapat mengatur fragmen href ke string ini.

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

Cara pertama akan memperlakukan negara baru sebagai lokasi baru (jadi tombol kembali akan membawa mereka ke lokasi sebelumnya). Yang terakhir tidak.


sumber
Apakah ada cara untuk menambahkan entri ke riwayat bookmark tanpa menyegarkan halaman? Mengatur lokasi (seperti pada contoh pertama Anda) akan menyebabkan penyegaran, bukan?
Drew Noakes
melakukan document.location.replace juga akan mengarahkan browser ke url itu (baru mencobanya di konsol chrome)
Omu
3

SWFAddress berfungsi dalam proyek Flash & Javascript dan memungkinkan Anda membuat URL yang dapat bookmark (menggunakan metode hash yang disebutkan di atas) serta memberi Anda dukungan tombol kembali.

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


sumber
3

Metode window.location.hash adalah cara yang disukai untuk melakukan sesuatu. Untuk penjelasan tentang bagaimana melakukannya, Pola Ajax - URL unik .

YUI memiliki implementasi dari pola ini sebagai modul, yang meliputi pekerjaan khusus IE untuk mendapatkan tombol kembali bekerja bersama dengan menulis ulang alamat menggunakan hash. Manajer Riwayat Peramban YUI .

Kerangka kerja lain juga memiliki implementasi yang serupa. Poin penting adalah jika Anda ingin riwayat bekerja bersama dengan penulisan ulang alamat, browser yang berbeda memerlukan cara penanganan yang berbeda. (Ini dirinci dalam artikel tautan pertama.)

IE membutuhkan hack berbasis iframe, di mana Firefox akan menghasilkan riwayat ganda menggunakan metode yang sama.

Drew Noakes
sumber
3

Jika OP atau orang lain masih mencari cara untuk melakukan modifikasi riwayat browser untuk mengaktifkan keadaan, menggunakan pushState dan replaceState, seperti yang disarankan oleh IESUS, adalah cara yang 'tepat' untuk melakukannya sekarang. Ini keuntungan utama daripada location.hash tampaknya menciptakan url yang sebenarnya, bukan hanya hash. Jika riwayat browser menggunakan hash disimpan, dan kemudian ditinjau kembali dengan javascript dinonaktifkan, aplikasi tidak akan berfungsi, karena hash tidak dikirim ke server. Namun, jika pushState telah digunakan, seluruh rute akan dikirim ke server, yang kemudian dapat Anda bangun untuk merespons rute-rute tersebut dengan tepat. Saya melihat contoh di mana template kumis yang sama digunakan pada server dan sisi klien. Jika klien mengaktifkan javascript, ia akan mendapatkan respons cepat dengan menghindari bolak-balik ke server, tetapi aplikasi akan bekerja dengan baik tanpa javascript. Dengan demikian, aplikasi dapat dengan anggun menurunkan tanpa adanya javascript.

Juga, saya percaya ada beberapa kerangka kerja di luar sana, dengan nama seperti history.js. Untuk peramban yang mendukung HTML5, ia menggunakan pushState, tetapi jika peramban tidak mendukung itu, ia secara otomatis kembali menggunakan hash.

Neil
sumber
2

Periksa apakah pengguna 'di' halaman, ketika Anda mengklik pada bilah url, javascript mengatakan Anda berada di luar halaman. Jika Anda mengubah bilah url dan tekan 'ENTER' dengan simbol '#' di dalamnya maka Anda masuk ke halaman lagi, tanpa mengklik pada halaman secara manual dengan kursor mouse, maka perintah event keyboad (document.onkeypress) dari javascript akan dapat memeriksa apakah itu masuk dan aktifkan javascript untuk pengalihan. Anda dapat memeriksa apakah pengguna berada di halaman dengan window.onfocus dan memeriksa apakah dia keluar dengan window.onblur.

Ya itu mungkin.

;)

Marcelo
sumber
Ini adalah cara saya melihat elegan untuk mengubah halaman ketika pengguna mengedit url bar dengan simbol #.
Marcelo