Xóa tham số URL mà không làm mới trang


153

Tôi đang cố gắng loại bỏ mọi thứ sau dấu "?" trong url trình duyệt trên tài liệu đã sẵn sàng.

Đây là những gì tôi đang cố gắng:

jQuery(document).ready(function($) {

var url = window.location.href;
    url = url.split('?')[0];
});

Tôi có thể làm điều này và thấy nó hoạt động dưới đây:

jQuery(document).ready(function($) {

var url = window.location.href;
    alert(url.split('?')[0]);
});

Có hai biểu mẫu trên một trang và khi một biểu mẫu được gửi, nó sẽ thêm một sản phẩm vào giỏ hàng và nối thêm một tham số dài vào url sau khi làm mới trang. Vì vậy, tôi muốn có thể loại bỏ tham số đó khi tài liệu đã sẵn sàng và nó bắt đầu bằng một?
Derek

1
Nếu bạn muốn làm mới trang, tại sao phải chờ đợi .ready()? Bạn không cần đợi để chuyển hướng đến một URL mới hoặc chỉ sử dụng .pushState()như khuyến nghị.
jfriend00

Câu trả lời:


227

TL; DR

1- Để sửa đổi URL hiện tại và thêm / bơm(URL sửa đổi mới) như một mục URL mới vào danh sách lịch sử, sử dụng pushState:

window.history.pushState({}, document.title, "/" + "my-new-url.html");

2- Để thay thế URL hiện tại mà không cần thêm nó vào các mục lịch sử, hãy sử dụng replaceState:

window.history.replaceState({}, document.title, "/" + "my-new-url.html");

3- Tùy thuộc vào logic kinh doanh của bạn , pushStatesẽ hữu ích trong các trường hợp như:

  • bạn muốn hỗ trợ nút quay lại của trình duyệt

  • bạn muốn tạo một URL mới , thêm / chèn / đẩy URL mới vào các mục lịch sử và làm cho URL hiện tại

  • cho phép người dùng đánh dấu trang với cùng tham số (để hiển thị cùng nội dung)

  • để lập trình truy cập các dữ liệu thông qua stateObjsau đó phân tích từ neo


Theo tôi hiểu từ nhận xét của bạn, bạn muốn xóa URL của mình mà không cần chuyển hướng nữa.

Lưu ý rằng bạn không thể thay đổi toàn bộ URL. Bạn chỉ có thể thay đổi những gì xuất hiện sau tên miền. Điều này có nghĩa là bạn không thể thay đổi www.example.com/nhưng bạn có thể thay đổi những gì đến sau.com/

www.example.com/old-page-name => can become =>  www.example.com/myNewPaage20180322.php

Lý lịch

Chúng tôi có thể sử dụng:

1- Phương thức PushState () nếu bạn muốn thêm một URL được sửa đổi mới vào các mục lịch sử.

2- Phương thức thay thế () nếu bạn muốn cập nhật / thay thế mục lịch sử hiện tại .

.replaceState()hoạt động chính xác như .pushState()ngoại trừ việc .replaceState() sửa đổi mục lịch sử hiện tại thay vì tạo một mục mới. Lưu ý rằng điều này không ngăn cản việc tạo một mục mới trong lịch sử trình duyệt toàn cầu.


.replaceState()đặc biệt hữu ích khi bạn muốn cập nhật đối tượng trạng thái hoặc URL của mục lịch sử hiện tại để đáp ứng với một số hành động của người dùng.


Để làm điều đó tôi sẽ sử dụng phương thức PushState () cho ví dụ này hoạt động tương tự như định dạng sau:

var myNewURL = "my-new-URL.php";//the new URL
window.history.pushState("object or string", "Title", "/" + myNewURL );

Cảm thấy tự do để thay thế pushStatevới replaceStatedựa trên yêu cầu của bạn.

Bạn có thể thay thế các paramter "object or string"với {}"Title"với document.titlenên Statment cuối cùng sẽ trở thành:

window.history.pushState({}, document.title, "/" + myNewURL );

Các kết quả

Hai dòng mã trước sẽ tạo một URL như:

https://domain.tld/some/randome/url/which/will/be/deleted/

Để trở thành:

https://domain.tld/my-new-url.php

Hoạt động

Bây giờ hãy thử một cách tiếp cận khác. Nói rằng bạn cần giữ tên của tập tin. Tên tệp xuất hiện sau cuối cùng /và trước chuỗi truy vấn ?.

http://www.someDomain.com/really/long/address/keepThisLastOne.php?name=john

Sẽ là:

http://www.someDomain.com/keepThisLastOne.php

Một cái gì đó như thế này sẽ làm cho nó hoạt động:

 //fetch new URL
 //refineURL() gives you the freedom to alter the URL string based on your needs. 
var myNewURL = refineURL();

//here you pass the new URL extension you want to appear after the domains '/'. Note that the previous identifiers or "query string" will be replaced. 
window.history.pushState("object or string", "Title", "/" + myNewURL );


//Helper function to extract the URL between the last '/' and before '?' 
//If URL is www.example.com/one/two/file.php?user=55 this function will return 'file.php' 
 //pseudo code: edit to match your URL settings  

   function refineURL()
{
    //get full URL
    var currURL= window.location.href; //get current address

    //Get the URL between what's after '/' and befor '?' 
    //1- get URL after'/'
    var afterDomain= currURL.substring(currURL.lastIndexOf('/') + 1);
    //2- get the part before '?'
    var beforeQueryString= afterDomain.split("?")[0];  

    return beforeQueryString;     
}

CẬP NHẬT:

Đối với một người hâm mộ lót, hãy thử điều này trong bảng điều khiển / con bọ lửa của bạn và URL trang này sẽ thay đổi:

    window.history.pushState("object or string", "Title", "/"+window.location.href.substring(window.location.href.lastIndexOf('/') + 1).split("?")[0]);

URL trang này sẽ thay đổi từ:

http://stackoverflow.com/questions/22753052/remove-url-parameters-without-refreshing-page/22753103#22753103

Đến

http://stackoverflow.com/22753103#22753103

Lưu ý: như Samuel Liew đã chỉ ra trong các bình luận bên dưới, tính năng này chỉ được giới thiệu cho HTML5.

Một cách tiếp cận khác là thực sự chuyển hướng trang của bạn (nhưng bạn sẽ mất chuỗi truy vấn `? ', Nó vẫn cần thiết hay dữ liệu đã được xử lý?).

window.location.href =  window.location.href.split("?")[0]; //"http://www.newurl.com";


2
Bạn đã quên đề cập rằng đây chỉ là một tính năng HTML5. developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/NH
Samuel Liew

Tại sao bạn thoát khỏi dấu gạch chéo cuối cùng? Điều đó có liên quan gì đến câu hỏi của OP? Họ chỉ muốn thoát khỏi chuỗi truy vấn. Dấu hỏi đầu tiên xác định phần đầu của chuỗi truy vấn.
jfriend00

6
replaceStatecó vẻ phù hợp hơn, nhưng pushStatecũng sẽ hoạt động, đó là cho đến khi bạn bắt đầu nhấp vào nút quay lại và chuyển tiếp trong trình duyệt và bạn nhận ra có một lý do có toàn bộ thư viện để làm việc với API Lịch sử.
adeneo

@ jfriend00 dựa trên hành vi của hàm, những gì bạn thêm vào tham số thứ ba sẽ được đặt trong URL sau tên miền, nghĩa là sau tên miền / như trong www.example.com/. Có khả năng OP có thể có một vài / giữa tên miền và? trong trường hợp trang web nằm trong một thư mục con, do đó, tùy thuộc vào anh ấy / cô ấy để trích xuất và thực hiện sàng lọc url tốt hơn vì câu hỏi là về cách chọn url, bây giờ làm thế nào để lấy chính xác.
Mohammed Joraid

Tôi chỉ nói rằng bạn không cần điều này url.substring(url.lastIndexOf('/') + 1);cả. url.split("?")[0]sẽ nhận được phần trước dấu chấm hỏi đầu tiên, đó là tất cả những gì tôi nghĩ OP yêu cầu. Câu hỏi của OP hỏi: "Tôi đang cố xóa mọi thứ sau dấu"? "Trong url trình duyệt".
jfriend00

156

Đây là tất cả sai lệch, bạn không bao giờ muốn thêm vào lịch sử trình duyệt trừ khi bạn muốn đi đến một trang khác trong một ứng dụng trang duy nhất. Nếu bạn muốn xóa các tham số mà không thay đổi trong trang, bạn phải sử dụng:

window.history.replaceState(null, null, window.location.pathname);

3
KISS (Keep là ngu ngốc và đơn giản). OP yêu cầu loại bỏ tất cả sau? và đây là câu trả lời đơn giản nhất bạn có thể nhận được cho những gì anh ấy yêu cầu!
Warface

Không hoạt động trên firefox. Khi làm mới, nhận thông số vẫn xuất hiện. Hoạt động bằng cả đẩy và thay thế. window.history.replaceState ({page: location.pathname}, document.title, window.location.pathname); window.history.pushState ({page: location.pathname}, document.title, window.location.pathname);
Ajay Singh

1
history.replaceState (null, null, location.pathname + location.hash) - thêm location.hash nếu bạn không muốn xóa phần đó
eselk

29

một cách đơn giản để làm điều này, hoạt động trên bất kỳ trang nào, yêu cầu HTML 5

// get the string following the ?
var query = window.location.search.substring(1)

// is there anything there ?
if(query.length) {
   // are the new history methods available ?
   if(window.history != undefined && window.history.pushState != undefined) {
        // if pushstate exists, add a new state to the history, this changes the url without reloading the page

        window.history.pushState({}, document.title, window.location.pathname);
   }
}

Điều này làm việc tốt đáng kinh ngạc. Thật không may, tôi không có manh mối đầu tiên về lý do tại sao nó hoạt động. Biết ơn tất cả như nhau.
Matt Cremeens

1
hai dòng đầu tiên kiểm tra nếu có bất cứ điều gì sau? . .pathname là một url cục bộ trừ truy vấn và trừ tên miền và tiền tố ( domain.com/THIS?notthis )
Martijn Scheffer


23

Tôi tin rằng phương pháp tốt nhất và đơn giản nhất cho việc này là:

var newURL = location.href.split("?")[0];
window.history.pushState('object', document.title, newURL);

11

nếu tôi có một thẻ đặc biệt ở cuối URL của mình như: http://domain.com/?tag=12345 Đây là đoạn mã dưới đây để xóa thẻ đó bất cứ khi nào nó xuất hiện trong URL:

<script>
// Remove URL Tag Parameter from Address Bar
if (window.parent.location.href.match(/tag=/)){
    if (typeof (history.pushState) != "undefined") {
        var obj = { Title: document.title, Url: window.parent.location.pathname };
        history.pushState(obj, obj.Title, obj.Url);
    } else {
        window.parent.location = window.parent.location.pathname;
    }
}
</script>

Điều này đưa ra ý tưởng để xóa một hoặc nhiều (hoặc tất cả) tham số khỏi URL

Với window.location.pathname, về cơ bản bạn có được mọi thứ trước '?' trong url.

var pathname = window.location.pathname; // Chỉ trả về đường dẫn

var url = window.location.href; // Trả về URL đầy đủ


Tôi không chắc đây là câu trả lời, nhưng bản thân câu hỏi không rõ ràng :)
Martijn Scheffer

@MartijnScheffer đúng, tôi đã cải thiện câu trả lời để trả lời câu hỏi ban đầu, cảm ơn bạn đã lưu ý.
Tarik

10

Tôi muốn xóa chỉ một param success. Đây là cách bạn có thể làm điều này:

let params = new URLSearchParams(location.search)
params.delete('success')
history.replaceState(null, '', '?' + params + location.hash)

Điều này cũng giữ lại #hash.


URLSearchParamssẽ không hoạt động trên IE, nhưng đang hoạt động trên Edge . Bạn có thể sử dụng một polyfill hoặc có thể sử dụng chức năng trợ giúp ngây thơ cho hỗ trợ IE:

function take_param(key) {
    var params = new Map(location.search.slice(1).split('&')
        .map(function(p) { return p.split(/=(.*)/) }))   
    var value = params.get(key)
    params.delete(key)
    var search = Array.from(params.entries()).map(
        function(v){ return v[0]+'='+v[1] }).join('&')
    return {search: search ? '?' + search : '', value: value}
}

Điều này có thể được sử dụng như:

history.replaceState(
    null, '', take_param('success').search + location.hash)

Giải pháp tuyệt vời, có cách nào để không thêm '?' nếu không có thông số nào được thông qua?
ricks

2
@RickS Tất nhiên, việc take_paramnày đã được thực hiện, nhưng bạn có thể thực URLSearchParamshiện tương tự bằng cách làm : history.replaceState(null, '', (params ? '?' + params : '') + location.hash). Hoặc tuy nhiên bạn thích.
odinho - Velmont

8

Giải pháp tốt hơn :

window.history.pushState(null, null, window.location.pathname);

6

Không có giải pháp nào trong số này thực sự hiệu quả với tôi, đây là chức năng tương thích với IE11 cũng có thể loại bỏ nhiều tham số:

/**
* Removes URL parameters
* @param removeParams - param array
*/
function removeURLParameters(removeParams) {
  const deleteRegex = new RegExp(removeParams.join('=|') + '=')

  const params = location.search.slice(1).split('&')
  let search = []
  for (let i = 0; i < params.length; i++) if (deleteRegex.test(params[i]) === false) search.push(params[i])

  window.history.replaceState({}, document.title, location.pathname + (search.length ? '?' + search.join('&') : '') + location.hash)
}

removeURLParameters(['param1', 'param2'])

2
//Joraid code is working but i altered as below. it will work if your URL contain "?" mark or not
//replace URL in browser
if(window.location.href.indexOf("?") > -1) {
    var newUrl = refineUrl();
    window.history.pushState("object or string", "Title", "/"+newUrl );
}

function refineUrl()
{
    //get full url
    var url = window.location.href;
    //get url after/  
    var value = url = url.slice( 0, url.indexOf('?') );
    //get the part after before ?
    value  = value.replace('@System.Web.Configuration.WebConfigurationManager.AppSettings["BaseURL"]','');  
    return value;     
}

1

Để xóa tất cả các tham số, mà không cần làm mới trang, VÀ nếu bạn đang sử dụng HTML5, thì bạn có thể làm điều này:

history.pushState({}, '', 'index.html' ); //replace 'index.html' with whatever your page name is

Điều này sẽ thêm một mục trong lịch sử trình duyệt. Bạn cũng có thể xem xét replaceStatenếu bạn không muốn thêm một mục mới và chỉ muốn thay thế mục cũ.


0

Trong sử dụng jquery <

window.location.href =  window.location.href.split("?")[0]

6
Không có gì về điều đó
j08691

0

Dưới đây là một lớp lót ES6 bảo vệ hàm băm vị trí và không gây ô nhiễm lịch sử trình duyệt bằng cách sử dụng replaceState:

(l=>{window.history.replaceState({},'',l.pathname+l.hash)})(location)

Bạn có thể thêm một số thông tin về điều này, thật khó để hiểu những gì nó đang làm.
ricks

2
$ đối tượng locationaka toàn cầu window.location, do đó, hàm có quyền truy cập vào toàn cầu locationlphần còn lại là cơ bản thay thế như trong tất cả các câu trả lời khác, anh ta ghép tên đường dẫn và hàm băm (example.com/#hash) làm url mới. Hy vọng nó có thể tiêu hóa được, nếu không cho tôi biết
Can Rau

@Can tại sao không chỉ sử dụng window.history.replaceState({}, '', location.pathname + location.hash)? ;)
Fabian von Ellerts

@FabianvonEllerts Câu hỏi hay thực sự, không thực sự chắc chắn rằng chỉ có điều bạn không phải viết location2 lần 😁 nhưng không cần gán nó cho một biến 😉 hoặc có nhiều hơn cho Joey không?
Cần Rau
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.