แก้ไข URL ของแถบที่อยู่ในแอป AJAX เพื่อให้ตรงกับสถานะปัจจุบัน


166

ฉันกำลังเขียนแอป AJAX แต่เมื่อผู้ใช้เลื่อนผ่านแอปฉันต้องการให้ URL ในแถบที่อยู่อัปเดตแม้ว่าจะไม่มีการโหลดหน้าซ้ำ โดยทั่วไปฉันต้องการให้พวกเขาคั่นหน้าได้ทุกที่และกลับไปที่สถานะปัจจุบัน

ผู้คนจัดการกับการบำรุงรักษา RESTfulness ในแอพ AJAX อย่างไร


2
มันถูกใช้เพื่อระบุสถานะของแอพของคุณ แต่ไม่มีอะไรเกี่ยวข้องกับ "RESTfulness"
Mohamed

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

3
คำตอบที่ยอมรับถูกเขียนขึ้นเมื่อ 5 ปีก่อนและในขณะเดียวกันเราก็ได้ window.history.pushState เช่นเดียวกับ @Omu กล่าว location.hash มีปัญหามากมายและควรหลีกเลี่ยง
pcarvalho

ฉันได้แก้ไขคำตอบเพื่อให้วิธีการ pushState โดดเด่น
jasonjwwilliams

คำตอบ:


116

วิธีการทำเช่นนี้คือการจัดการlocation.hashเมื่อ AJAX อัปเดตส่งผลให้เกิดการเปลี่ยนแปลงสถานะที่คุณต้องการให้มี URL ที่ไม่ต่อเนื่อง ตัวอย่างเช่นหาก URL ของหน้าเว็บของคุณคือ:

http://example.com/

หากฟังก์ชันฝั่งไคลเอ็นต์เรียกใช้งานโค้ดนี้:

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

location.hash = 'foo';

จากนั้น URL ที่แสดงในเบราว์เซอร์จะได้รับการอัปเดตเป็น:

http://example.com/#foo

วิธีนี้ช่วยให้ผู้ใช้สามารถคั่นหน้าสถานะ "foo" ของหน้าและใช้ประวัติเบราว์เซอร์เพื่อนำทางระหว่างรัฐ

ด้วยกลไกนี้คุณจะต้องแยกส่วนแฮชของ URL ในฝั่งไคลเอ็นต์โดยใช้ JavaScript เพื่อสร้างและแสดงสถานะเริ่มต้นที่เหมาะสมเนื่องจากตัวระบุส่วน (ส่วนหลัง #) จะไม่ถูกส่งไปยัง เซิร์ฟเวอร์

ปลั๊กอินแฮชเชนของ Ben Almanช่วยให้คุณใช้งาน jQuery ได้อย่างง่ายดาย


ดูเหมือนว่าคุณพูดถูก นั่นเป็นวิธีการเดียว นี่ดูเหมือนคำอธิบายรายละเอียดที่ดีสำหรับคำแนะนำของคุณ: < ajaxpatterns.org/Unique_URLs >
jasonjwwilliams

@buymeasoda ขอบคุณสำหรับการแก้ไข; ฉันไม่แน่ใจว่าฉันคิดอะไรอยู่เมื่อฉันเขียนส่วนนั้น
เดฟวอร์ด

1
ว้าวคำตอบนี้มีประโยชน์มาก แม้ว่าตัวอย่าง URL จะสับสนเล็กน้อยดังนั้นอาจมีการแทนที่ลิงก์ด้วยชื่อเรื่องโดยอัตโนมัติ วิธีการแทนที่สิ่งเหล่านั้นด้วย example.com และ example.com/#foo เพื่อให้เราสามารถดู URL ทั้งหมดในแบบธรรมดา
Neil

4
@Pascal คุณสามารถทำได้ แต่เฉพาะในเบราว์เซอร์ที่รองรับ pushState ของ HTML5 ข้อมูลที่ดีเกี่ยวกับที่นี่: diveintohtml5.info/history.html
Dave Ward

1
ฉันสิ้นสุดการเป็นแฟนตัวยงของ history.js เพื่อให้ครอบคลุมฐานสำหรับความเข้ากันได้ของเบราว์เซอร์github.com/andreasbernhard/history.js
jocull

18

ดูเว็บไซต์เช่น book.cakephp.org เว็บไซต์นี้เปลี่ยน URL โดยไม่ต้องใช้แฮชและใช้ AJAX ฉันไม่แน่ใจว่ามันทำได้อย่างไร แต่ฉันพยายามคิดออก หากใครรู้แจ้งให้ฉันทราบ

นอกจากนี้ github.com เมื่อดูการนำทางภายในโครงการที่กำหนด


ฉันสังเกตเห็นว่าด้วย GitHub หนึ่งสัปดาห์หรือมากกว่านั้น พวกเขาทำเช่นนั้นบนโลกได้อย่างไร? ต้องย้อนกลับและตรวจสอบ
Drew Noakes

16
ดูเหมือนว่าพวกเขากำลังใช้ฟังก์ชัน javascript pushState () สิ่งนี้จะเพิ่มประวัติของเบราว์เซอร์ของคุณ ดูมันสิ มันค่อนข้างน่าสนใจและเท่ห์
daniel.wright

ขอบคุณสำหรับสิ่งนี้มันเป็นสิ่งที่ฉันกำลังมองหา ฉันสงสัยว่า GitHub ทำได้อย่างไร ตอนแรกฉันคิดว่ามันจะต้องโหลดซ้ำ แต่มีเพียงคำขอ AJAX ใน Opera มันโหลดหน้าเว็บซ้ำ
kamranicus

เทคนิคที่คล้ายกันนั้นถูกใช้โดย fb ขณะที่นำทางผ่านหน้าต่างๆของกลุ่มต่างๆ คุณมีคอลัมน์การนำทางด้านซ้ายซึ่งมีการกล่าวถึงกลุ่มต่างๆ เมื่อคุณคลิกที่ชื่อกลุ่มเฉพาะการเปลี่ยนแปลง URL และเฉพาะเนื้อหาของบานหน้าต่างเนื้อหาหลักจะเปลี่ยนไปพร้อมกับ URL (ไม่มีแฮช) ดังนั้นเมื่อผู้ใช้โหลดหน้าซ้ำพวกเขาจะไม่ถูกเปลี่ยนเส้นทางไปยังหน้าแรก แต่ไปที่หน้ากลุ่ม
Madeyedexter

17

ไม่น่าเป็นไปได้ที่ผู้เขียนต้องการโหลดซ้ำหรือเปลี่ยนเส้นทางผู้เยี่ยมชมเมื่อใช้ Ajax แต่ทำไมไม่ใช้ HTML5 ของpushState/ replaceState?

คุณจะสามารถแก้ไขแถบที่อยู่ได้มากเท่าที่คุณต้องการ รับ URL ที่ดูเป็นธรรมชาติด้วย AJAX

ลองดูรหัสในโปรเจ็กต์ล่าสุดของฉัน: http://iesus.se/


11

นี่คล้ายกับสิ่งที่เควินพูด คุณสามารถให้สถานะไคลเอนต์ของคุณเป็นวัตถุจาวาสคริปต์บางส่วนและเมื่อคุณต้องการบันทึกสถานะคุณจะทำให้วัตถุเป็นอนุกรม (โดยใช้การเข้ารหัส JSON และ base64) จากนั้นคุณสามารถตั้งค่าส่วนของ href เป็นสายอักขระนี้

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

วิธีแรกจะถือว่าสถานะใหม่เป็นตำแหน่งใหม่ (ดังนั้นปุ่มย้อนกลับจะนำพวกเขาไปยังตำแหน่งก่อนหน้า) หลังไม่ได้


มีวิธีเพิ่มรายการในประวัติบุ๊กมาร์กโดยไม่ต้องรีเฟรชหน้าเว็บหรือไม่ การตั้งค่าตำแหน่ง (ตามตัวอย่างแรก) จะทำให้รีเฟรชใช่มั้ย
Drew Noakes

ทำ document.location.replace จะเปลี่ยนเส้นทางเบราว์เซอร์ไปยัง URL นั้น (ลองใช้ในคอนโซล Chrome)
Omu

3

SWFAddress ทำงานในโครงการ Flash & Javascript และช่วยให้คุณสร้าง URL ที่คั่นหน้าได้ (ใช้วิธีแฮชที่กล่าวถึงข้างต้น) รวมถึงให้การสนับสนุนปุ่มย้อนกลับแก่คุณ

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


3

วิธี window.location.hash เป็นวิธีที่ต้องการในการทำสิ่งต่าง ๆ สำหรับคำอธิบายของวิธีการที่จะทำมันเป็น รูปแบบที่อาแจ็กซ์ - URL ที่ไม่ซ้ำกัน

YUI มีการนำรูปแบบนี้มาใช้เป็นโมดูลซึ่งรวมถึงการทำงานเฉพาะของ IE เพื่อให้ปุ่มย้อนกลับทำงานพร้อมกับเขียนที่อยู่ใหม่โดยใช้แฮช ผู้จัดการประวัติศาสตร์ยูอิเบราว์เซอร์

กรอบงานอื่นมีการใช้งานที่คล้ายกันเช่นกัน จุดสำคัญคือถ้าคุณต้องการให้ประวัติทำงานพร้อมกับการเขียนที่อยู่ซ้ำเบราว์เซอร์ต่าง ๆ ต้องการวิธีการจัดการที่แตกต่างกัน (นี่คือรายละเอียดในบทความลิงค์แรก)

IE ต้องการแฮ็คที่ใช้ iframe ซึ่ง Firefox จะสร้างประวัติสองครั้งโดยใช้วิธีการเดียวกัน


3

หาก OP หรือคนอื่น ๆ ยังคงมองหาวิธีที่จะแก้ไขประวัติเบราว์เซอร์เพื่อเปิดใช้งานสถานะโดยใช้ pushState และ replaceState ตามที่ IESUS แนะนำเป็นวิธีที่ถูกต้องในการทำทันที มันเป็นข้อได้เปรียบหลักเหนือ location.hash ดูเหมือนว่ามันจะสร้าง URL จริงไม่ใช่เพียงแค่แฮช หากมีการบันทึกประวัติเบราว์เซอร์ที่ใช้แฮชจากนั้นเข้าชมอีกครั้งโดยปิดการใช้งานจาวาสคริปต์แอปจะไม่ทำงานเนื่องจากแฮชจะไม่ถูกส่งไปยังเซิร์ฟเวอร์ อย่างไรก็ตามหากมีการใช้ pushState เส้นทางทั้งหมดจะถูกส่งไปยังเซิร์ฟเวอร์ซึ่งคุณสามารถสร้างเพื่อตอบสนองเส้นทางที่เหมาะสมได้ ฉันเห็นตัวอย่างที่มีการใช้เทมเพลตหนวดแบบเดียวกันทั้งบนเซิร์ฟเวอร์และฝั่งไคลเอ็นต์ หากลูกค้าเปิดใช้งานจาวาสคริปต์เขาจะได้รับการตอบสนองที่รวดเร็วโดยหลีกเลี่ยงการไปยังเซิร์ฟเวอร์ แต่แอพพลิเคชั่นจะทำงานได้อย่างสมบูรณ์แบบหากไม่มีจาวาสคริปต์ ดังนั้นแอปสามารถลดลงอย่างงดงามได้หากไม่มีจาวาสคริปต์

นอกจากนี้ฉันเชื่อว่ามีบางกรอบออกไปด้วยชื่อเช่น history.js สำหรับเบราว์เซอร์ที่รองรับ HTML5 จะใช้ pushState แต่หากเบราว์เซอร์ไม่รองรับเบราว์เซอร์นั้นจะกลับมาใช้แฮชโดยอัตโนมัติ


2

ตรวจสอบว่าผู้ใช้ 'ใน' หน้าเมื่อคุณคลิกที่แถบ url จาวาสคริปต์บอกว่าคุณจะออกจากหน้า หากคุณเปลี่ยนแถบ URL และกด 'ENTER' พร้อมสัญลักษณ์ '#' ภายในแถบนั้นคุณจะเข้าสู่หน้านั้นอีกครั้งโดยไม่ต้องคลิกที่หน้าด้วยตนเองด้วยเคอร์เซอร์ของเมาส์จากนั้นคำสั่งเหตุการณ์ keyboad (document.onkeypress) จาก javascript จะ สามารถตรวจสอบว่ามันเข้ามาและเปิดใช้งานจาวาสคริปต์สำหรับการเปลี่ยนเส้นทางหรือไม่ คุณสามารถตรวจสอบว่าผู้ใช้อยู่ในหน้าเว็บด้วย window.onfocus หรือไม่และตรวจสอบว่าเขาออกจาก window.onblur หรือไม่

ใช่มันเป็นไปได้

;)


นี่คือวิธีที่ฉันเห็นการเปลี่ยนแปลงหน้าเว็บเมื่อผู้ใช้แก้ไขแถบ URL ด้วยสัญลักษณ์ #
Marcelo
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.