รับตำแหน่งแฮช URL และใช้ใน jQuery


135

ฉันต้องการรับค่าหลังแฮชใน URL ของเพจปัจจุบันจากนั้นจึงสามารถใช้ค่านี้ในฟังก์ชันใหม่ ... เช่น

URL อาจเป็น

www.example.com/index.html#foo

และฉันต้องการใช้สิ่งนี้ร่วมกับรหัสต่อไปนี้

$('ul#foo:first').show();

ฉันคิดว่า / หวังว่าจะมีวิธีการจับสิ่งนี้และเปลี่ยนเป็นตัวแปรที่ฉันสามารถใช้ในโค้ดชิ้นที่สองได้


8
ฉันไม่มีรหัสสำหรับคุณ แต่คุณควรตรวจสอบให้แน่ใจว่าได้ล้างข้อมูลที่ป้อนให้เรียบร้อยเพราะดูเหมือนจะสุกงอมสำหรับการฉีดโค้ด
Nate B

การเข้าใจว่าคำถามนี้มีอายุเกือบสิบปีแล้ว'ul#foo:first'ไม่สมเหตุสมผลเนื่องจาก ID ต้องไม่ซ้ำกันดังนั้นการเพิ่ม:firstในตัวเลือกจึงซ้ำซ้อนเว้นแต่คุณจะทำซ้ำ ID ซึ่งไม่ถูกต้อง โปรดทราบว่าแม้ทศวรรษที่ผ่านมา ID ซ้ำก็ยังไม่ถูกต้อง
j08691

ยังคงผิดเมื่อทศวรรษที่แล้ว
ดักลาส

คำตอบ:


283

หมายเหตุบรรณาธิการ:แนวทางด้านล่างนี้มีผลกระทบด้านความปลอดภัยที่ร้ายแรงและอาจทำให้ผู้ใช้ของคุณถูกโจมตี XSS ได้ทั้งนี้ขึ้นอยู่กับเวอร์ชันของ jQuery ที่คุณใช้ สำหรับรายละเอียดเพิ่มเติมโปรดดูที่การอภิปรายของการโจมตีที่เป็นไปได้ในการแสดงความคิดเห็นในคำตอบนี้หรือคำอธิบายนี้ในการรักษาความปลอดภัยกองแลกเปลี่ยน

คุณสามารถใช้location.hashคุณสมบัติเพื่อคว้าแฮชของหน้าปัจจุบัน:

var hash = window.location.hash;
$('ul'+hash+':first').show();

โปรดสังเกตว่าคุณสมบัตินี้มี#สัญลักษณ์ที่จุดเริ่มต้นอยู่แล้ว

อันที่จริงคุณไม่จำเป็นต้อง:firstใช้ตัวเลือกหลอกเนื่องจากคุณใช้ตัวเลือก IDถือว่า ID ไม่ซ้ำกันภายใน DOM

ในกรณีที่คุณต้องการรับแฮชจากสตริง URL คุณสามารถใช้String.substringวิธีการ:

var url = "http://example.com/file.htm#foo";
var hash = url.substring(url.indexOf('#')); // '#foo'

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


30
โปรดทราบว่าตัวเลือก jQuery สามารถใช้เพื่อเรียกใช้โค้ดจาวาสคริปต์ที่กำหนดเองได้ดังนั้นการใช้แฮชที่ไม่ได้รับการรับรองจึงไม่ปลอดภัยอย่างน่ากลัวและไม่ปลอดภัย มีการแก้ไขแบบ half-assed สำหรับสิ่งนี้ใน jQuery เวอร์ชันล่าสุดสำหรับตัวเลือกที่มี # ก่อนโค้ดที่แทรก แต่คุณยังมีความเสี่ยงหากคุณลบเครื่องหมาย # ออกจากจุดเริ่มต้นของตำแหน่งแฮช เช่น. var hash = location.hash.slice(1); $('ul.item'+hash).show().append($('#content'));สิ่งนี้จะเรียกใช้แท็กสคริปต์ที่ใส่ไว้ในแฮช มันเป็นนิสัยที่ดีที่จะใช้แทน$('body').find('ul'+hash+':first') $('ul'+hash+':first')
Tgr

40
เบราว์เซอร์บางตัวส่งคืนสัญลักษณ์แฮชและบางตัวไม่ใช้ดังนั้นจึงปลอดภัยกว่าที่จะใช้:var hash = location.hash.replace('#', '');
ทิม

12
อลิซดำเนินการเว็บไซต์บ็อบเข้าเยี่ยมชมตรวจสอบสิทธิ์และรับคุกกี้เซสชัน (เวลาผ่านไปสักพักบ็อบอาจปิดเบราว์เซอร์ของเขาด้วยซ้ำ) ชาร์ลีส่งอีเมลให้บ็อบบอกว่า "ดูลิงก์สุดเจ๋งนี้!" Bob เปิดลิงก์ซึ่งนำไปสู่ไซต์ที่ควบคุมโดย Charlie หน้านี้เปลี่ยนเส้นทางเบราว์เซอร์ของ Bob ไปยังหน้าบนไซต์ของ Alice พร้อมกับเพย์โหลดการโจมตีในแฮช เพย์โหลดถูกดำเนินการและเนื่องจากเบราว์เซอร์ยังคงจำคุกกี้ได้จึงสามารถส่งไปยัง Charlie ได้
Tgr

2
@Tgr ขอบคุณสำหรับการอธิบายและเชื่อมต่อจุดต่างๆ ตัวอย่างที่เป็นรูปธรรมนี้ทำให้ฉัน (และหวังว่าคนอื่น ๆ ) มีแนวโน้มที่จะระมัดระวังในการรักษาความปลอดภัยมากขึ้น
snapfractalpop

2
@buffer: $(userInput)โดยทั่วไปไม่ปลอดภัยเนื่องจาก$มีการโอเวอร์โหลดและอาจค้นหาโหนดที่มีอยู่หรือสร้างใหม่ขึ้นอยู่กับว่าสตริงนั้นมี<>อักขระหรือไม่ $(document).find(userInput)จะค้นหาโหนดที่มีอยู่เสมอดังนั้นจึงไม่ปลอดภัยน้อยกว่า ดังกล่าวแนวทางปฏิบัติที่ดีที่สุดคือทำความสะอาดข้อมูลที่ผู้ใช้ป้อนอยู่เสมอเช่นหากคุณใช้รหัสตัวอักษรและตัวเลขตรวจสอบให้แน่ใจว่าเป็นตัวเลขและตัวอักษร
Tgr

35

location.hash ไม่ปลอดภัยสำหรับ IEในกรณีของ IE (รวมถึง IE9) หากเพจของคุณมี iframe หลังจากรีเฟรชด้วยตนเองภายในเนื้อหา iframe แล้วจะได้รับตำแหน่งค่าแฮชเป็นค่าเก่า (ค่าสำหรับการโหลดหน้าแรก) ในขณะที่ค่าที่ดึงด้วยตนเองนั้นแตกต่างจากตำแหน่งดังนั้นให้ดึงผ่าน document.URL

var hash = document.URL.substr(document.URL.indexOf('#')+1) 

7
อัปเดต: document.URL ไม่มีค่าแฮชบน firefox 3.6 ดังนั้น location.href จึงปลอดภัย var hash = location.href.substr (location.href.indexOf ('#') + 1)
Deepak Patil

4

สำหรับผู้ที่กำลังมองหาโซลูชันจาวาสคริปต์ที่แท้จริง

 document.getElementById(location.hash.substring(1)).style.display = 'block'

หวังว่านี่จะช่วยคุณประหยัดเวลาได้บ้าง


3

เนื่องจาก jQuery 1.9 :targetตัวเลือกจะจับคู่แฮช URL คุณสามารถทำได้:

$(":target").show(); // or $("ul:target").show();

ซึ่งจะเลือกองค์ประกอบที่มี ID ตรงกับแฮชและแสดง


มีวิธีแยกแฮชเป็นสตริงแทนรหัสการจับคู่หรือไม่
ina

@ina คุณหมายถึงรับแฮชจาก jQuery :targetเป็นสตริงหรือไม่? ถ้าอย่างนั้นฉันไม่เชื่ออย่างนั้น
j08691

2

ฉันขอแนะนำให้ใช้ cek ก่อนดีกว่าถ้าหน้าปัจจุบันมีแฮช undefinedมิฉะนั้นจะเป็น

$(window).on('load', function(){        
    if( location.hash && location.hash.length ) {
       var hash = decodeURIComponent(location.hash.substr(1));
       $('ul'+hash+':first').show();;
    }       
});

1

ฉันใช้สิ่งนี้เพื่อจัดการกับผลกระทบด้านความปลอดภัยที่ระบุไว้ในคำตอบของ @ CMS

// example 1: www.example.com/index.html#foo

// load correct subpage from URL hash if it exists
$(window).on('load', function () {
    var hash = window.location.hash;
    if (hash) {
        hash = hash.replace('#',''); // strip the # at the beginning of the string
        hash = hash.replace(/([^a-z0-9]+)/gi, '-'); // strip all non-alphanumeric characters
        hash = '#' + hash; // hash now equals #foo with example 1

        // do stuff with hash
        $( 'ul' + hash + ':first' ).show();
        // etc...
    }
});
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.