删除URL参数而不刷新页面


153

我正在尝试删除“?”之后的所有内容。在浏览器上的URL上准备好文档。

这是我正在尝试的:

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

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

我可以做到这一点,并在下面的作品中看到它:

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

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

一页上有两种形式,提交一种形式后,它将产品添加到购物车,并在页面刷新后在URL后面添加一个长参数。因此,我希望能够在文档准备好并以?开头时删除该参数。
2014年

1
如果要刷新页面,为什么要等待.ready()?您无需等待即可重定向到新的URL .pushState(),也无需按照Joraid的建议使用。
jfriend00 2014年

Answers:


227

TL; DR

1-要修改当前URL并将其(新修改的URL)添加/注入为历史列表中的新URL条目,请使用:pushState

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

2-要替换当前网址而不将添加到历史记录条目中,请使用replaceState

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

3- 根据您的业务逻辑pushState在以下情况下将很有用:

  • 您想要支持浏览器的后退按钮

  • 您想要创建一个 URL, /插入/推入新URL历史记录条目中,并使其成为当前URL

  • 允许用户使用相同的参数为页面添加书签(以显示相同的内容)

  • 以编程访问数据通过stateObj接着从锚解析


从您的评论中可以了解到,您希望清除URL而无需再次重定向。

请注意,您无法更改整个URL。您可以更改域名后的名称。这意味着您无法更改,www.example.com/但可以更改之后的内容.com/

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

背景

我们可以用:

1- 如果要向历史记录条目添加新的修改的URL,则使用pushState()方法

2- 如果要更新/替换当前历史记录条目,则使用replaceState()方法

.replaceState().pushState()除了.replaceState() 修改当前的历史记录条目而不是创建新的历史记录条目之外,操作方式完全相同。请注意,这不会阻止在全局浏览器历史记录中创建新条目。


.replaceState()当您要响应某些用户操作而更新状态对象或当前历史记录条目的URL时,此功能特别有用。


为此,我将在本示例中使用pushState()方法,该方法的工作方式与以下格式类似:

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

随意更换pushStatereplaceState根据您的要求。

您可以替换放慢参数"object or string"{}"Title"document.title因此最终statment将变为:

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

结果

前两行代码将创建一个URL,例如:

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

成为:

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

行动

现在让我们尝试另一种方法。假设您需要保留文件名。文件名位于最后一个/查询字符串之后?

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

将会:

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

这样的事情将使其工作:

 //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;     
}

更新:

对于一名班轮迷,请在您的控制台/萤火虫中尝试一下,此页面URL将会更改:

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

此页面的网址将更改为:

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

http://stackoverflow.com/22753103#22753103

注意:正如Samuel Liew在下面的注释中指出的,此功能仅针对引入HTML5

另一种方法是实际重定向页面(但是您将丢失查询字符串'?',是否仍需要它或数据已被处理?)。

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



你为什么要从最后一个斜杠剥离?这与OP的问题有什么关系?他们只想摆脱查询字符串。第一个问号定义查询字符串的开头。
jfriend00 2014年

6
replaceState似乎更合适,但pushState也可以正常使用,即直到您开始单击浏览器中的“后退”和“前进”按钮,并且您才意识到有理由使用整个库来使用History API。
2014年

@ jfriend00基于函数的行为,您在第三个参数中添加的内容将放置在域名之后的URL中,即在域名/之后的URL中,如www.example.com/。OP可能在域名和?之间包含多个/。如果该网站位于子目录中,则由他(她)决定是否要进行锻炼并进行更好的网址优化,因为问题在于如何更改网址,现在如何正确获取网址。
Mohammed Joraid 2014年

我只是说你根本不需要这个url.substring(url.lastIndexOf('/') + 1);url.split("?")[0]将在第一个问号之前得到该零件,这是我认为OP所要求的。OP的问题询问:“我正在尝试删除浏览器URL中“?”之后的所有内容”。
jfriend00 2014年

156

这些都是误导性的,除非您要转到单页应用程序中的其他页面,否则您永远都不想添加到浏览器历史记录中。如果要删除参数而不更改页面,则必须使用:

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

3
吻(保持愚蠢和简单)。OP要求删除所有内容后?这是他所要求的最简单的答案!
Warface

不适用于Firefox。刷新时,get参数仍然出现。可以同时使用推入和替换。window.history.replaceState({page:location.pathname},document.title,window.location.pathname); window.history.pushState({page:location.pathname},document.title,window.location.pathname);
阿杰·辛格

1
history.replaceState(null,null,location.pathname + location.hash)-如果您不想删除该部分,请添加location.hash
eselk

29

一种简单的方法,可在任何页面上使用,需要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);
   }
}

这非常好用。不幸的是,我不知道它为什么起作用。一样感谢。
Matt Cremeens '17

1
前两行检查?之后是否有任何内容?(子字符串只是删除了'?'),然后我检查浏览器是否支持新的pushstate调用,最后我使用pushstate将状态添加到url堆栈中(可以在该堆栈中推送和弹出url),window.location .pathname是本地URL减去查询和减去域名和前缀(domain.com/THIS?notthis
马亭雅伯


23

我相信最好,最简单的方法是:

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

11

如果我在URL末尾有一个特殊标记,例如:http : //domain.com/? tag=12345,则以下代码可在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>

这样就可以从网址中删除一个或多个(或所有)参数

使用window.location.pathname,您基本上可以得到“?”之前的所有内容 在网址中。

var pathname = window.location.pathname; //仅返回路径

var url = window.location.href; //返回完整的URL


我不确定这是否能回答问题,但问题本身尚不清楚:)
Martijn Scheffer

@MartijnScheffer对,我改进了答案,以回答原始问题,谢谢。
塔里克

10

我只想删除一个参数success。这是您可以执行的操作:

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

这也保留了下来#hash


URLSearchParams不会在IE上运行,但会在Edge上运行。您可以使用polyfill或可以使用纯稚的辅助函数来支持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}
}

可以像这样使用:

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

很棒的解决方案,有什么办法不加'?' 如果没有通过参数?
瑞克斯

2
@RickS当然,take_param已经在执行此操作,但是您可以URLSearchParams通过执行以下操作来进行相同操作:history.replaceState(null, '', (params ? '?' + params : '') + location.hash)。或者,但是您喜欢。
奥迪尼奥-费尔蒙'18

8

更好的解决方案:

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

6

这些解决方案均不适用于我,这是IE11兼容功能,还可以删除多个参数:

/**
* 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

要清除所有参数而不进行页面刷新,并且如果您使用的是HTML5,则可以执行以下操作:

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

这将在浏览器历史记录中添加一个条目。您还可以考虑replaceState是否不希望添加新条目,而只想替换旧条目。


0

在jquery中使用<

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

6
没有关于jQuery的内容
j08691

0

这是一个ES6衬板,它可以保留位置哈希值,并且不会通过使用replaceState以下内容污染浏览器的历史记录:

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

您能否添加一些有关此的更多信息,很难理解它在做什么。
瑞克斯

2
@RickS这是一个IIFE(立即调用的函数表达式),这就是为什么将它包装在括号()(location)中的原因,第一个括号使它能够保留为自己的匿名函数,最后(location)立即调用传递给它的函数全局locationaka window.location对象,因此该函数可以访问全局变量,location因为l其余的都是基本的replaceState,如在所有其他答案中一样,他将路径名和哈希(example.com/#hash)连接为新的url。希望它的消化,如果不是让我知道😉
灿劳

@为什么不能只使用window.history.replaceState({}, '', location.pathname + location.hash)?;)
Fabian von Ellerts

@FabianvonEllerts实际上,这是一个很好的问题,不是很确定,您不必写location2次😁不需要将其分配给变量😉还是Joey吗?
Can Rau
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.