Mendapatkan lokasi hash URL, dan menggunakannya di jQuery

135

Saya ingin mendapatkan nilai setelah hash di URL halaman saat ini dan kemudian dapat menerapkannya di fungsi baru ... mis.

URL bisa jadi

www.example.com/index.html#foo

Dan saya ingin menggunakan ini bersama dengan potongan kode berikut

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

Saya berasumsi / berharap ada cara untuk mengambil ini, dan mengubahnya menjadi variabel yang kemudian dapat saya gunakan di bagian kode kedua.

Robbie White
sumber
8
Saya tidak memiliki kode apa pun untuk Anda, tetapi Anda harus memastikan untuk membersihkan masukan, karena ini tampaknya sudah matang untuk injeksi kode.
Nate B
Memahami bahwa pertanyaan ini hampir berumur satu dekade, 'ul#foo:first'tidak masuk akal karena ID harus unik, oleh karena itu menambahkan :firstke pemilih berlebihan, kecuali Anda menduplikasi ID yang tidak valid. Perhatikan bahwa bahkan satu dekade lalu, ID berulang masih tidak valid.
j08691
Masih salah satu dekade yang lalu
Douglas

Jawaban:

283

Catatan editor: pendekatan di bawah ini memiliki implikasi keamanan yang serius dan, tergantung pada versi jQuery yang Anda gunakan, dapat membuat pengguna Anda terkena serangan XSS. Untuk lebih jelasnya lihat pembahasan kemungkinan serangan di komentar di jawaban ini atau penjelasan di Security Stack Exchange ini .

Anda dapat menggunakan location.hashproperti untuk mengambil hash dari halaman saat ini:

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

Perhatikan bahwa properti ini sudah berisi #simbol di awal.

Sebenarnya Anda tidak memerlukan :firstpseudo-selector karena Anda menggunakan ID selector , diasumsikan bahwa ID dalam DOM unik .

Jika Anda ingin mendapatkan hash dari string URL, Anda dapat menggunakan String.substringmetode:

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

Saran: Ketahuilah bahwa pengguna dapat mengubah hash sesuai keinginannya, memasukkan apa pun ke pemilih Anda, Anda harus memeriksa hash sebelum menggunakannya.

Christian C. Salvadó
sumber
30
Perhatikan bahwa pemilih jQuery dapat digunakan untuk mengeksekusi kode javascript khusus, jadi menggunakan hash yang tidak dibersihkan sangatlah tidak aman. Ada perbaikan setengah-setengah untuk ini di versi jQuery terbaru untuk pemilih yang berisi # sebelum kode yang dimasukkan, tetapi Anda masih berisiko jika Anda menghapus tanda # dari awal location.hash. E. g. var hash = location.hash.slice(1); $('ul.item'+hash).show().append($('#content'));ini akan menjalankan tag skrip yang dimasukkan ke dalam hash. Ini adalah kebiasaan yang baik untuk digunakan $('body').find('ul'+hash+':first')sebagai gantinya $('ul'+hash+':first').
Tgr
40
Beberapa browser mengembalikan simbol hash, dan beberapa tidak, jadi lebih aman untuk menggunakan:var hash = location.hash.replace('#', '');
Tim
12
Alice menjalankan situs web, Bob mengunjunginya, mengautentikasi, dan menerima cookie sesi. (Beberapa waktu mungkin berlalu di sini, Bob bahkan mungkin menutup browsernya.) Charlie mengirimi Bob sebuah email yang mengatakan "lihat tautan keren ini!". Bob membuka link tersebut, yang mengarah ke situs yang dikendalikan oleh Charlie. Halaman tersebut mengarahkan browser Bob ke halaman di situs Alice dengan muatan serangan di hash. Muatan dijalankan, dan karena browser masih mengingat cookie, itu hanya dapat mengirimnya ke Charlie.
Tgr
2
@Tgr, terima kasih telah menjelaskan dan menghubungkan titik-titiknya. Contoh konkret ini membuat saya (dan semoga orang lain) lebih cenderung waspada dalam menjaga keamanan.
snapfractalpop
2
@ Buffer: $(userInput)umumnya tidak aman karena $kelebihan beban dan mungkin mencari node yang ada atau membuat yang baru tergantung pada apakah string berisi <>karakter. $(document).find(userInput)akan selalu mencari node yang ada sehingga kurang aman. Meskipun demikian, praktik terbaiknya adalah selalu membersihkan input pengguna, misalnya jika Anda menggunakan id alfanumerik, pastikan itu alfanumerik.
Tgr
35

location.hash tidak aman untuk IE , dalam kasus IE (termasuk IE9), jika halaman Anda berisi iframe, maka setelah refresh manual di dalam konten iframe dapatkan nilai location.hash lama (nilai untuk pemuatan halaman pertama). sedangkan nilai yang diambil secara manual berbeda dari location.hash jadi selalu ambil melalui document.URL

var hash = document.URL.substr(document.URL.indexOf('#')+1) 
Deepak Patil
sumber
7
Pembaruan: document.URL tidak mengandung nilai hash pada firefox 3.6 jadi location.href aman var hash = location.href.substr (location.href.indexOf ('#') + 1)
Deepak Patil
4

Bagi mereka yang mencari solusi javascript murni

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

Semoga ini menghemat waktu Anda.

Matas Vaitkevicius
sumber
3

Sejak jQuery 1.9, :targetpemilih akan cocok dengan hash URL. Jadi Anda bisa melakukan:

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

Yang akan memilih elemen dengan ID yang cocok dengan hash dan menampilkannya.

j08691
sumber
apakah ada cara untuk mengekstrak hash sebagai string daripada match id?
ina
@ina Maksud Anda mendapatkan hash dari jQuery :targetsebagai string? Jika demikian saya tidak percaya begitu.
j08691
2

Saya sarankan lebih baik cek dulu jika halaman saat ini memiliki hash. Kalau tidak, itu akan terjadi undefined.

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

Saya menggunakan ini untuk mengatasi implikasi keamanan yang dicatat dalam jawaban @ 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...
    }
});
squarecandy
sumber