从URL中删除查询字符串

204
什么是JavaScript中从路径中删除查询字符串的简单方法? 我见过一个使用window.location.search的JQuery插件。但我不能这样做:在我的情况下,URL是从AJAX设置的变量。
var testURL = '/Products/List?SortDirection=dsc&Sort=price&Page=3&Page2=3&SortOrder=dsc'

13年后的编辑

在过去的十年中,Javascript获得了一些Url处理功能。

12个回答

435

获取这个的简单方法是:

function getPathFromUrl(url) {
  return url.split("?")[0];
}

对于那些也希望在不存在查询字符串时移除哈希(不是原问题的一部分)的人,需要进行一些额外操作:

function stripQueryStringAndHashFromPath(url) {
  return url.split("?")[0].split("#")[0];
}

编辑

@caub(最初是@crl)建议一个更简单的组合,可以同时适用于查询字符串和哈希(虽然它使用了RegExp,但如果有人对此有问题,也可以采用这种方法):

function getPathFromUrl(url) {
  return url.split(/[?#]/)[0];
}

4
在这种情况下,实际上使用split()比substring()更好。 - Daniel Vassallo
12
边际优化,如果有必要的话(可能并不重要):split('?', 1)[0]。该代码意为:以问号为分隔符,将字符串拆分成两个部分,只保留第一部分。 - bobince
@ChristianVielma:这个 ? 是一个字符串字面量,不是一个正则表达式。 - Robusto
函数 fnRemoveQsParameter(url, parameter) { 返回 url.split("?")[parameter].split("#")[parameter]; } - user1531040
8
嘿,Robusto,为什么不用.split(/[?#]/)[0] - caub
显示剩余4条评论

37

第二次更新: 为了提供全面的答案,我正在对各种回答中提出的三种方法进行基准测试。

var testURL = '/Products/List?SortDirection=dsc&Sort=price&Page=3&Page2=3';
var i;

// Testing the substring method
i = 0;
console.time('10k substring');
while (i < 10000) {
    testURL.substring(0, testURL.indexOf('?'));
    i++;
}
console.timeEnd('10k substring');

// Testing the split method
i = 0;
console.time('10k split');
while (i < 10000) {
    testURL.split('?')[0]; 
    i++;
}
console.timeEnd('10k split');

// Testing the RegEx method
i = 0;
var re = new RegExp("[^?]+");
console.time('10k regex');
while (i < 10000) {
    testURL.match(re)[0]; 
    i++;
}
console.timeEnd('10k regex');

在Mac OS X 10.6.2上,Firefox 3.5.8的结果如下:

10k substring:  16ms
10k split:      25ms
10k regex:      44ms

在Mac OS X 10.6.2上,使用Chrome 5.0.307.11的结果:

10k substring:  14ms
10k split:      20ms
10k regex:      15ms

请注意,substring方法在功能上不如其他两种方法,在URL没有查询字符串时返回空字符串。另外两种方法将按预期返回完整的URL。然而有趣的是,在Firefox中,substring方法是最快的。


第1个更新:实际上,由Robusto提出的split()方法是一个更好的解决方案,因为它可以在没有查询字符串的情况下使用:

var testURL = '/Products/List?SortDirection=dsc&Sort=price&Page=3&Page2=3';
testURL.split('?')[0];    // Returns: "/Products/List"

var testURL2 = '/Products/List';
testURL2.split('?')[0];    // Returns: "/Products/List"
抱歉,我只能使用英文进行沟通和回答问题。
var testURL = '/Products/List?SortDirection=dsc&Sort=price&Page=3&Page2=3';
testURL.substring(0, testURL.indexOf('?'));    // Returns: "/Products/List"

13
非常全面,但是......为什么?显然最灵活、最合适的方法胜出,速度在这里完全不重要。 - deceze
2
@deceze:只是出于好奇……还有因为在Angus的回答评论中有关于正则表达式方法性能的争论。 - Daniel Vassallo
7
非常有趣,丹尼尔。如果我需要在页面上进行10K个URL解析的话,我会寻求另一种职业。 :) - Robusto
1
我真的有点惊讶,居然可以在44毫秒内完成10k个正则表达式匹配。将来,我想我会更倾向于更多地使用它们。 - TheGerm

29

也许这是一个老问题,但我尝试过这种方法来删除查询参数。对我来说似乎很顺利,因为我需要重新加载并删除查询参数。

window.location.href = window.location.origin + window.location.pathname;

我使用简单的字符串拼接操作,所以我猜性能会很好。但仍然值得与此答案中的代码片段进行比较。


在我看来,这是最佳解决方案。是否存在任何缺点或情况下无法使用? - Daniel
原因是OP明确表示不能使用window.location,必须完全在裸字符串上操作。 - Robusto

21

var u = new URL('https://server.de/test?q#h')
u.hash = ''
u.search = ''
console.log(u.toString())


1
这是本主题中唯一有效的答案。 - polkovnikov.ph
这种方法更好,而且在Node.js中也可以使用,但是如果你需要每秒处理成千上万个URL,性能会稍微差一些。 - Rodrigo Amaral

7

我能理解以前的事情有多痛苦,在现代你可以非常容易地获取它,就像下面这样:

let url = new URL('https://example.com?foo=1&bar=2&foo=3');
let params = new URLSearchParams(url.search);

// Delete the foo parameter.
params.delete('foo'); //Query string is now: 'bar=2'

// now join the query param and host
let newUrl =  url.origin + '/' + params.toString();

4
let params = url.searchParams 就足够了。 - Unmitigated

4
var path = "path/to/myfile.png?foo=bar#hash";

console.log(
    path.replace(/(\?.*)|(#.*)/g, "")
);

2
使用标准的URL方法来处理:
/**
 * @param {string} path - A path starting with "/"
 * @return {string}
 */
function getPathname(path) {
  return new URL(`http://_${path}`).pathname
}

getPathname('/foo/bar?cat=5') // /foo/bar

@Brad,当他只是返回路径名时,协议有什么关系呢? - The Fool
1
@The Fool - 否则new URL()将会失败并报告“无效的URL”错误信息。 - Tom

2
一种简单的方法是按照以下步骤操作:
public static String stripQueryStringAndHashFromPath(String uri) {
 return uri.replaceAll(("(\\?.*|\\#.*)"), "");
}

1
如果您对正则表达式感兴趣...
var newURL = testURL.match(new RegExp("[^?]+"))

1
正则表达式速度较慢 - 采用简单快速的方法。 - Aristos
这个操作不是为此而设计的。在Firefox中,对长URL进行1000次操作只需要5毫秒。 - plodder
1
@Angus:你的循环会出现“A script may be busy…”的错误,因为你忘记了增加a++;。在我的Firefox 3.6和iMac 2.93Ghz Core 2 Duo上进行测试,使用正则表达式需要8毫秒,而使用分割方法只需要3毫秒…尽管如此,还是要给你点赞,因为这仍然是另一种选择。 - Daniel Vassallo
1
谢谢 - 我几分钟前就修好了!- 但重点是,即使对于正则表达式操作需要 0.000005 秒的情况下,性能对任何解决方案都不是问题 :-) - plodder
1
match() 返回一个对象。你可能不想要那个。在它上面调用 toString()(或者 +'')。 - bobince
1
Bob - 不错的发现。事实上,它返回一个匹配数组 - 在这种情况下是一个字符串数组。因此,testURL.match(new RegExp("[^?]+"))[0] 这么做。 - plodder

1
如果使用backbone.js(其中包含url锚点作为路由),则可能会出现URL查询字符串
  1. before url anchor:

    var url = 'http://example.com?a=1&b=3#routepath/subpath';
    
  2. after url anchor:

    var url = 'http://example.com#routepath/subpath?a=1&b=3';
    

解决方案:

window.location.href.replace(window.location.search, '');
// run as: 'http://example.com#routepath/subpath?a=1&b=3'.replace('?a=1&b=3', '');

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接