Lấy vị trí băm URL và sử dụng nó trong jQuery


135

Tôi muốn nhận giá trị sau khi băm trong URL của trang hiện tại và sau đó có thể áp dụng giá trị này trong một chức năng mới ... ví dụ:

URL có thể là

www.example.com/index.html#foo

Và tôi muốn sử dụng nó cùng với đoạn mã sau

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

Tôi hơi giả định / hy vọng có một cách nào đó để nắm bắt điều này và biến nó thành một biến mà sau đó tôi có thể sử dụng trong đoạn mã thứ hai.


8
Tôi không có bất kỳ mã nào cho bạn, nhưng bạn nên đảm bảo vệ sinh đầu vào, vì điều này dường như đã chín muồi cho việc tiêm mã.
Nate B

Hiểu rằng câu hỏi này đã gần một thập kỷ, 'ul#foo:first'không có ý nghĩa vì ID phải là duy nhất, do đó việc thêm :firstvào bộ chọn là không cần thiết, trừ khi bạn sao chép ID không hợp lệ. Lưu ý rằng thậm chí một thập kỷ trước, ID lặp lại vẫn không hợp lệ.
j08691

Vẫn còn sai một thập kỷ trước
Douglas

Câu trả lời:


280

Lưu ý của biên tập viên: cách tiếp cận dưới đây có ý nghĩa bảo mật nghiêm trọng và, tùy thuộc vào phiên bản jQuery bạn đang sử dụng, có thể khiến người dùng của bạn bị tấn công XSS. Để biết thêm chi tiết, hãy xem thảo luận về cuộc tấn công có thể có trong các nhận xét về câu trả lời này hoặc giải thích này về Trao đổi ngăn xếp bảo mật .

Bạn có thể sử dụng thuộc location.hashtính để lấy hàm băm của trang hiện tại:

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

Lưu ý rằng thuộc tính này đã chứa #biểu tượng ở đầu.

Trên thực tế, bạn không cần :firstbộ chọn giả vì bạn đang sử dụng bộ chọn ID , giả sử rằng ID là duy nhất trong DOM.

Trong trường hợp bạn muốn lấy băm từ một chuỗi URL, bạn có thể sử dụng String.substringphương thức:

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

Lời khuyên: Hãy lưu ý rằng người dùng có thể thay đổi hàm băm theo ý muốn, tiêm bất cứ thứ gì vào bộ chọn của bạn, bạn nên kiểm tra hàm băm trước khi sử dụng.


30
Lưu ý rằng các bộ chọn jQuery có thể được sử dụng để thực thi mã javascript tùy chỉnh, do đó, sử dụng các giá trị băm không được xác thực là rất khủng khiếp, không an toàn khủng khiếp. Có một sửa chữa nửa vời cho điều này trong các phiên bản jQuery gần đây cho các bộ chọn có chứa # trước mã được chèn, nhưng bạn vẫn có nguy cơ nếu bạn xóa dấu # từ đầu location.hash. Ví dụ. var hash = location.hash.slice(1); $('ul.item'+hash).show().append($('#content'));điều này sẽ thực thi một thẻ script đặt trong hàm băm. Đó là một thói quen tốt để sử dụng $('body').find('ul'+hash+':first')thay vì $('ul'+hash+':first').
Tgr

40
Một số trình duyệt trả lại biểu tượng băm và một số thì không, vì vậy an toàn hơn khi sử dụng:var hash = location.hash.replace('#', '');
Tim

12
Alice điều hành một trang web, Bob truy cập nó, xác thực và nhận cookie phiên. (Một thời gian có thể trôi qua ở đây, Bob thậm chí có thể đóng trình duyệt của mình.) Charlie gửi cho Bob một bức thư có nội dung "hãy xem liên kết tuyệt vời này!". Bob mở liên kết, dẫn đến một trang web được kiểm soát bởi Charlie. Trang chuyển hướng trình duyệt của Bob đến một trang trên trang web của Alice với trọng tải tấn công trong hàm băm. Tải trọng được thực thi và vì trình duyệt vẫn còn nhớ các cookie, nên nó có thể gửi chúng cho Charlie.
Tgr

2
@Tgr, cảm ơn bạn đã xây dựng và kết nối các dấu chấm. Ví dụ cụ thể này làm cho tôi (và hy vọng những người khác) nghiêng về sự cảnh giác trong việc giữ an toàn cho mọi thứ.
snapfractalpop

2
@buffer: $(userInput)thường không an toàn vì $bị quá tải và có thể tìm kiếm các nút hiện có hoặc tạo các nút mới tùy thuộc vào việc chuỗi có chứa các <>ký tự hay không. $(document).find(userInput)sẽ luôn tìm kiếm các nút hiện có để nó ít an toàn hơn. Điều đó nói rằng, cách tốt nhất là luôn luôn vệ sinh đầu vào của người dùng, ví dụ: nếu bạn sử dụng id chữ số, hãy chắc chắn rằng đó là chữ và số.
Tgr

35

location.hash không an toàn cho IE , trong trường hợp IE (bao gồm IE9), nếu trang của bạn chứa iframe, thì sau khi làm mới thủ công bên trong nội dung iframe lấy location.hash giá trị cũ (giá trị cho tải trang đầu tiên). trong khi giá trị truy xuất thủ công khác với location.hash vì vậy hãy luôn truy xuất nó thông qua document.URL

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

7
Cập nhật: document.URL không chứa giá trị băm trên firefox 3.6 vì vậy location.href là an toàn var hash = location.href.substr (location.href.indexOf ('#') + 1)
Deepak Patil

4

Đối với những người đang tìm kiếm giải pháp javascript thuần túy

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

Hy vọng điều này sẽ giúp bạn tiết kiệm thời gian.


3

Kể từ jQuery 1.9, :targetbộ chọn sẽ khớp với hàm băm URL. Vì vậy, bạn có thể làm:

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

Mà sẽ chọn phần tử có ID khớp với hàm băm và hiển thị nó.


Có cách nào để trích xuất hàm băm dưới dạng chuỗi thay vì khớp id không?
ina

@ina Bạn có nghĩa là lấy hàm băm từ jQuery :targetnhư một chuỗi? Nếu vậy tôi không tin như vậy.
j08691

1

Tôi sẽ đề nghị cek tốt hơn trước nếu trang hiện tại có hàm băm. Nếu không nó sẽ được undefined.

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

1

Tôi đang sử dụng điều này để giải quyết các hàm ý bảo mật được ghi chú trong câu trả lời của @ 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...
    }
});
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.