如何在JavaScript中删除查询字符串参数?


127

除了使用正则表达式之外,还有没有更好的方法可以从标准Ja​​vaScript中的URL字符串中的查询字符串中删除参数?

到目前为止,这是我想出的方法,似乎可以在我的测试中使用,但是我不希望重新发明querystring解析!

function RemoveParameterFromUrl( url, parameter ) {

    if( typeof parameter == "undefined" || parameter == null || parameter == "" ) throw new Error( "parameter is required" );

    url = url.replace( new RegExp( "\\b" + parameter + "=[^&;]+[&;]?", "gi" ), "" ); "$1" );

    // remove any leftover crud
    url = url.replace( /[&;]$/, "" );

    return url;
}

Answers:


178
"[&;]?" + parameter + "=[^&;]+"

似乎很危险,因为它的参数“ bar”会匹配:

?a=b&foobar=c

另外,如果parameter包含RegExp中特殊的任何字符(例如“。”),它将失败。而且它不是全局正则表达式,因此只会删除该参数的一个实例。

我不会为此使用简单的RegExp,而是会解析其中的参数并丢失您不需要的参数。

function removeURLParameter(url, parameter) {
    //prefer to use l.search if you have a location/link object
    var urlparts = url.split('?');   
    if (urlparts.length >= 2) {

        var prefix = encodeURIComponent(parameter) + '=';
        var pars = urlparts[1].split(/[&;]/g);

        //reverse iteration as may be destructive
        for (var i = pars.length; i-- > 0;) {    
            //idiom for string.startsWith
            if (pars[i].lastIndexOf(prefix, 0) !== -1) {  
                pars.splice(i, 1);
            }
        }

        return urlparts[0] + (pars.length > 0 ? '?' + pars.join('&') : '');
    }
    return url;
}

关于与foobar匹配的bar的要点。我已经更新了原始正则表达式,要求输入吗?或开头的[&;]。还请仔细阅读您的解决方案以进行考虑...
Matthew Lock

5
如果要摆脱“?” 如果删除后没有参数,请添加一个if条件以测试pars.length == 0,如果它为0,则使“ url = urlparts [0]”而不是附加“?”。
johnmcaliley,2010年

2
比较URL片段和encodeURIComponent(parameter)是否安全?如果URL对参数名称的编码不同,该怎么办?例如,“ two%20words”和“ two + words”。为了解决这个问题,最好将参数名称解​​码并将其作为普通字符串进行比较。
Adrian Pronk

9
进行了轻微的改进,因此,当删除最终的URL参数时,“?” 也被删除:将行更改url= urlparts[0]+'?'+pars.join('&');url= urlparts[0] + (pars.length > 0 ? '?' + pars.join('&') : "");
Cody S

2
@ ktutnik / @ JonasAxelsson URL查询参数自然不区分大小写。
bobince

30

现代浏览器提供URLSearchParams了使用搜索参数的界面。哪个具有delete按名称删除参数的方法。

if (typeof URLSearchParams !== 'undefined') {
  const params = new URLSearchParams('param1=1&param2=2&param3=3')
  
  console.log(params.toString())
  
  params.delete('param2')
  
  console.log(params.toString())

} else {
  console.log(`Your browser ${navigator.appVersion} does not support URLSearchParams`)
}


2
请注意,URLSearchParamsIE,Edge 16和iOS 10.2 Safari不支持。(ref:caniuse.com/#feat=urlsearchparams
khiav reoy

3
@khiavreoy是的。像答案中的前两个词一样,它给出的链接是相同的:)
Yury Tarabanko

23

从bobince答案复制,但使其在查询字符串中支持问号,例如

http://www.google.com/search?q=test???+something&aq=f

URL中包含多个问号是否有效?

function removeUrlParameter(url, parameter) {
  var urlParts = url.split('?');

  if (urlParts.length >= 2) {
    // Get first part, and remove from array
    var urlBase = urlParts.shift();

    // Join it back up
    var queryString = urlParts.join('?');

    var prefix = encodeURIComponent(parameter) + '=';
    var parts = queryString.split(/[&;]/g);

    // Reverse iteration as may be destructive
    for (var i = parts.length; i-- > 0; ) {
      // Idiom for string.startsWith
      if (parts[i].lastIndexOf(prefix, 0) !== -1) {
        parts.splice(i, 1);
      }
    }

    url = urlBase + '?' + parts.join('&');
  }

  return url;
}

2
我认为???语法无效,并且永远不会出现在URL`中。

@torazaburo看看我发布的stackoverflow问题:“ URL中包含多个问号是否有效?”,答案似乎是肯定的。同样是几年前,所以我不记得详细信息,但是如果处理不当,就会遇到问题。
LukePH '16

我并不是说它们在现实世界中不存在,并且可能希望能够处理它们,但是在格式正确的URL中,问号是“保留字符”,除问号外的任何问号都可以。引入查询参数应该是URL编码的。

1
您可能需要替换最后一行,return url.endsWith("?") ? url.slice(0,-1) : url;以涵盖要删除的参数是查询字符串中唯一的参数的情况
Konamiman

@Konamiman例如,从google.com/search?q=test???&aq=f删除'aq'时,这将更改参数数据,但我明白了,即使清理URL也很不错?不会造成任何伤害。逻辑只需要确保最后一个?也是第一个?
LukePH '16

21

我看不到正则表达式解决方案的主要问题。但是,不要忘记保留片段标识符(之后的文本#)。

这是我的解决方案:

function RemoveParameterFromUrl(url, parameter) {
  return url
    .replace(new RegExp('[?&]' + parameter + '=[^&#]*(#.*)?$'), '$1')
    .replace(new RegExp('([?&])' + parameter + '=[^&]*&'), '$1');
}

准确地说,是的-您需要对.参数名称中的字符进行转义。


1
这是一个改进的正则表达式,当参数没有值时(即'ex.com?removeMe')起作用,并且不会替换片段(即'ex.com?#&dont=removeMe')或路径(即' ex.com/&dont=removeMe'):url.replace(new RegExp('^([^#]*\?)(([^#]*)&)?' + parameter + '(\=[^&#]*)?(&|#|$)' ), '$1$3$5').replace(/^([^#]*)((\?)&|\?(#|$))/,'$1$3$4')
斯蒂芬·哈里斯

这行不通,斯蒂芬·哈里斯(Stephen M. Harris)。尝试给您的代码一个空字符串作为参数,看看会发生什么……
David Fischer

15

您可以使用以下方法更改URL:

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

这样,您可以不使用搜索参数覆盖URL,在使用GET参数后,我用它来清理URL。


13

任何对正则表达式解决方案感兴趣的人,我都会组合使用此函数来添加/删除/更新querystring参数。不提供值将删除该参数,提供一个将添加/更新参数。如果没有提供URL,它将从window.location中获取。该解决方案还考虑了URL的锚点。

function UpdateQueryString(key, value, url) {
    if (!url) url = window.location.href;
    var re = new RegExp("([?&])" + key + "=.*?(&|#|$)(.*)", "gi"),
        hash;

    if (re.test(url)) {
        if (typeof value !== 'undefined' && value !== null)
            return url.replace(re, '$1' + key + "=" + value + '$2$3');
        else {
            hash = url.split('#');
            url = hash[0].replace(re, '$1$3').replace(/(&|\?)$/, '');
            if (typeof hash[1] !== 'undefined' && hash[1] !== null) 
                url += '#' + hash[1];
            return url;
        }
    }
    else {
        if (typeof value !== 'undefined' && value !== null) {
            var separator = url.indexOf('?') !== -1 ? '&' : '?';
            hash = url.split('#');
            url = hash[0] + separator + key + '=' + value;
            if (typeof hash[1] !== 'undefined' && hash[1] !== null) 
                url += '#' + hash[1];
            return url;
        }
        else
            return url;
    }
}

更新

删除查询字符串中的第一个参数时出现错误,我对正则表达式进行了重新设计,并进行了测试以包含修复程序。

更新2

@schellmax更新,修复了在紧靠井号之前删除查询字符串变量时井号符号丢失的情况


1
如果您有两个查询字符串并删除第一个查询字符串,则此方法不起作用。传入的url无效,因为?应该保留时将其删除。
Blake Niemyjski 2013年

1
@BlakeNiemyjski感谢您发现该错误,我更新了脚本,以包括第一个参数的解决方法
ellemayo 2013年

1
会在此处意外删除哈希:UpdateQueryString('a', null, 'http://www.test.com?a=b#c');
schellmax 2013年

很酷的功能,谢谢。仅供参考:将其与each()循环中的ignore数组键一起使用时,您可能需要url为每次替换迭代定义一个不断缩小的值。但是,这意味着您必须value在参数中输入a ,这会将查询字符串保留一半。为了解决这个问题,请使用undefinednull作为value参数,例如:url_from_last_iteration = UpdateQueryString(current_ignore_key, undefined/null, url_from_last_iteration);
dhaupin

7

假设您要从URI中删除key = val参数:

function removeParam(uri) {
   return uri.replace(/([&\?]key=val*$|key=val&|[?&]key=val(?=#))/, '');
}

效果很好,但是在正则表达式中转义第一个问号是不必要的,并且可能导致linter错误:/([&?]key=val*$|key=val&|[?&]key=val(?=#))/使用像lintlin这样的linter时可能更可取
quetzaluz


6

继承人一个完整的功能,用于基于此问题和此github gist添加和删除参数:https : //gist.github.com/excalq/2961415

var updateQueryStringParam = function (key, value) {

    var baseUrl = [location.protocol, '//', location.host, location.pathname].join(''),
        urlQueryString = document.location.search,
        newParam = key + '=' + value,
        params = '?' + newParam;

    // If the "search" string exists, then build params from it
    if (urlQueryString) {

        updateRegex = new RegExp('([\?&])' + key + '[^&]*');
        removeRegex = new RegExp('([\?&])' + key + '=[^&;]+[&;]?');

        if( typeof value == 'undefined' || value == null || value == '' ) { // Remove param if value is empty

            params = urlQueryString.replace(removeRegex, "$1");
            params = params.replace( /[&;]$/, "" );

        } else if (urlQueryString.match(updateRegex) !== null) { // If param exists already, update it

            params = urlQueryString.replace(updateRegex, "$1" + newParam);

        } else { // Otherwise, add it to end of query string

            params = urlQueryString + '&' + newParam;

        }

    }
    window.history.replaceState({}, "", baseUrl + params);
};

您可以添加如下参数:

updateQueryStringParam( 'myparam', 'true' );

然后像这样删除它:

updateQueryStringParam( 'myparam', null );

在这个线程中,许多人说正则表达式可能不是最好/稳定的解决方案……因此,我不能100%确定该东西是否存在某些缺陷,但据我测试,它工作得很好。


5

对于今天的浏览器,这是带有URL类的干净版本的remove查询参数

function removeUrlParameter(url, paramKey)
{
  var r = new URL(url);
  r.searchParams.delete(paramKey);
  return r.href;
}

旧版浏览器不支持URLSearchParams

https://caniuse.com/#feat=urlsearchparams

IE,Edge(低于17)和Safari(低于10.3)不支持URL类中的URLSearchParams。

填充胶

URLSearchParams仅polyfill

https://github.com/WebReflection/url-search-params

完整的Polyfill URL和URLSearchParams以匹配最新的WHATWG规范

https://github.com/lifaon74/url-polyfill


4

使用jQuery:

function removeParam(key) {
    var url = document.location.href;
    var params = url.split('?');
    if (params.length == 1) return;

    url = params[0] + '?';
    params = params[1];
    params = params.split('&');

    $.each(params, function (index, value) {
        var v = value.split('=');
        if (v[0] != key) url += value + '&';
    });

    url = url.replace(/&$/, '');
    url = url.replace(/\?$/, '');

    document.location.href = url;
}

3

以上版本为功能

function removeURLParam(url, param)
{
 var urlparts= url.split('?');
 if (urlparts.length>=2)
 {
  var prefix= encodeURIComponent(param)+'=';
  var pars= urlparts[1].split(/[&;]/g);
  for (var i=pars.length; i-- > 0;)
   if (pars[i].indexOf(prefix, 0)==0)
    pars.splice(i, 1);
  if (pars.length > 0)
   return urlparts[0]+'?'+pars.join('&');
  else
   return urlparts[0];
 }
 else
  return url;
}


2

据我所知,以上方法均不能处理普通参数和数组参数。这是一个。

function removeURLParameter(param, url) {
    url = decodeURI(url).split("?");
    path = url.length == 1 ? "" : url[1];
    path = path.replace(new RegExp("&?"+param+"\\[\\d*\\]=[\\w]+", "g"), "");
    path = path.replace(new RegExp("&?"+param+"=[\\w]+", "g"), "");
    path = path.replace(/^&/, "");
    return url[0] + (path.length
        ? "?" + path
        : "");
}

function addURLParameter(param, val, url) {
    if(typeof val === "object") {
        // recursively add in array structure
        if(val.length) {
            return addURLParameter(
                param + "[]",
                val.splice(-1, 1)[0],
                addURLParameter(param, val, url)
            )
        } else {
            return url;
        }
    } else {
        url = decodeURI(url).split("?");
        path = url.length == 1 ? "" : url[1];
        path += path.length
            ? "&"
            : "";
        path += decodeURI(param + "=" + val);
        return url[0] + "?" + path;
    }
}

如何使用它:

url = location.href;
    -> http://example.com/?tags[]=single&tags[]=promo&sold=1

url = removeURLParameter("sold", url)
    -> http://example.com/?tags[]=single&tags[]=promo

url = removeURLParameter("tags", url)
    -> http://example.com/

url = addURLParameter("tags", ["single", "promo"], url)
    -> http://example.com/?tags[]=single&tags[]=promo

url = addURLParameter("sold", 1, url)
    -> http://example.com/?tags[]=single&tags[]=promo&sold=1

当然,要更新参数,只需删除然后添加即可。随时为其创建虚拟功能。


path.replace(new RegExp("&?"+param+"=[\\w]+", "g"), "");我将正则表达式更改[\\w]*为包括“ param =”之类的参数而没有值。
Tomas Prado

2

该线程上的所有响应都有一个缺陷,即它们不保留URL的锚点/片段部分。

因此,如果您的网址如下所示:

http://dns-entry/path?parameter=value#fragment-text

然后替换“参数”

您将丢失您的片段文本。

以下是针对此问题的先前答案(通过LukePH进行绑定)的改编:

function removeParameter(url, parameter)
{
  var fragment = url.split('#');
  var urlparts= fragment[0].split('?');

  if (urlparts.length>=2)
  {
    var urlBase=urlparts.shift(); //get first part, and remove from array
    var queryString=urlparts.join("?"); //join it back up

    var prefix = encodeURIComponent(parameter)+'=';
    var pars = queryString.split(/[&;]/g);
    for (var i= pars.length; i-->0;) {               //reverse iteration as may be destructive
      if (pars[i].lastIndexOf(prefix, 0)!==-1) {   //idiom for string.startsWith
        pars.splice(i, 1);
      }
    }
    url = urlBase + (pars.length > 0 ? '?' + pars.join('&') : '');
    if (fragment[1]) {
      url += "#" + fragment[1];
    }
  }
  return url;
}

1
轻微改进,因此,当删除最终的URL参数时,“?” 也被删除:更改行url = urlBase+'?'+pars.join('&');url = urlBase + (pars.length > 0 ? '?' + pars.join('&') : "");
Cody S


2

这里是一个解决方案:

  1. 使用URLSearchParams(不难理解正则表达式)
  2. 在不重新加载的情况下更新搜索栏中的URL
  3. 维护 URL的所有其他部分(例如,哈希)
  4. ?如果删除了最后一个参数,则删除查询字符串中的多余内容
function removeParam(paramName) {
    let searchParams = new URLSearchParams(window.location.search);
    searchParams.delete(paramName);
    if (history.replaceState) {
        let searchString = searchParams.toString().length > 0 ? '?' + searchParams.toString() : '';
        let newUrl = window.location.protocol + "//" + window.location.host + window.location.pathname +  searchString + window.location.hash;
        history.replaceState(null, '', newUrl);
    }
}

注意:如其他答案所指出,URLSearchParams是 IE不支持,因此请使用polyfill


2

如果是的实例URL,请使用的delete功能searchParams

let url = new URL(location.href);
url.searchParams.delete('page');

1

另一个直接和简单的答案是

let url = new URLSearchParams(location.search)
let key = 'some_key'

return url.has(key)
    ? location.href.replace(new RegExp(`[?&]${key}=${url.get(key)}`), '')
    : location.href

0

ssh_imov的解决方案的修改版本

function removeParam(uri, keyValue) {
      var re = new RegExp("([&\?]"+ keyValue + "*$|" + keyValue + "&|[?&]" + keyValue + "(?=#))", "i"); 
      return uri.replace(re, '');
    }

像这样打电话

removeParam("http://google.com?q=123&q1=234&q2=567", "q1=234");
// returns http://google.com?q=123&q2=567

发送参数值时要记住的一件事是将空间转换为%20
xeon zolt

0

这将返回没有任何GET参数的URL:

var href = document.location.href;
var search = document.location.search;
var pos = href.indexOf( search );
if ( pos !== -1 ){
    href = href.slice( 0, pos );
    console.log( href );
}

0

我实际上编写了以下函数来处理url参数,并以字符串的形式获取最终状态并重定向页面。希望它会受益。

function addRemoveUrlQuery(addParam = {}, removeParam = [], startQueryChar = '?'){

    let urlParams = new URLSearchParams(window.location.search);

    //Add param
    for(let i in addParam){
        if(urlParams.has(i)){ urlParams.set(i, addParam[i]); }
        else                { urlParams.append(i, addParam[i]); }
    }

    //Remove param
    for(let i of removeParam){
        if(urlParams.has(i)){
            urlParams.delete(i);
        }
    }

    if(urlParams.toString()){
        return startQueryChar + urlParams.toString();
    }

    return '';
}

例如,当我单击一个按钮时,我希望页面值被删除而类别值被添加。

let button = document.getElementById('changeCategory');
button.addEventListener('click', function (e) {

    window.location = addRemoveUrlQuery({'category':'cars'}, ['page']);

});

我认为这非常有用!


0

很高兴您滚动到这里。

我建议您通过下一个可能的解决方案来解决此任务:

  1. 您只需要支持现代浏览器(Edge> = 17)-使用URLSearchParams.delete()API。它是本机的,显然是解决此任务的最便捷方法。
  2. 如果这不是一个选项,则可能需要编写一个函数来执行此操作。这样的功能确实
    • 如果不存在参数,请勿更改URL
    • 删除没有值的网址参数,例如 http://google.com/?myparm
    • 删除带有值的网址参数,例如 http://google.com/?myparm=1
    • 删除URL参数是否在URL中两次,例如 http://google.com?qp=1&qpqp=2&qp=1
    • 不使用 for循环并且在循环过程中不修改数组
    • 更实用
    • 比regexp解决方案更具可读性
    • 使用之前,请确保您的网址未编码

在IE> 9(ES5版本)中工作

function removeParamFromUrl(url, param) {  // url: string, param: string
  var urlParts = url.split('?'),
      preservedQueryParams = '';

  if (urlParts.length === 2) {
    preservedQueryParams = urlParts[1]
      .split('&')
      .filter(function(queryParam) {
        return !(queryParam === param || queryParam.indexOf(param + '=') === 0)
      })
      .join('&');
  }

  return urlParts[0] +  (preservedQueryParams && '?' + preservedQueryParams); 
}

花式ES6版本

function removeParamFromUrlEs6(url, param) {
  const [path, queryParams] = url.split('?');
	let preservedQueryParams = '';

  if (queryParams) {
    preservedQueryParams = queryParams
      .split('&')
      .filter(queryParam => !(queryParam === param || queryParam.startsWith(`${param}=`)))
      .join('&');
  }

  return `${path}${preservedQueryParams && `?${preservedQueryParams}`}`;  
}

在这里查看其运作方式


0
function removeParamInAddressBar(parameter) {
    var url = document.location.href;
    var urlparts = url.split('?');

    if (urlparts.length >= 2) {
        var urlBase = urlparts.shift();
        var queryString = urlparts.join("?");

        var prefix = encodeURIComponent(parameter) + '=';
        var pars = queryString.split(/[&;]/g);
        for (var i = pars.length; i-- > 0;) {
            if (pars[i].lastIndexOf(prefix, 0) !== -1) {
                pars.splice(i, 1);
            }
        }

        if (pars.length == 0) {
            url = urlBase;
        } else {
            url = urlBase + '?' + pars.join('&');
        }

        window.history.pushState('', document.title, url); // push the new url in address bar
    }
    return url;
}

-1
const params = new URLSearchParams(location.search)
params.delete('key_to_delete')
console.log(params.toString())

这是一个非常老的问题的答案,并且已经有了公认的答案。请说明该答案提供的内容与其他答案有何不同。另外,答案应包括解释,而不仅仅是代码。
nurdyguy


-2
function removeQueryStringParameter(uri, key, value) 
{

var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");

    var separator = uri.indexOf('?') !== -1 ? "&" : "?";

    if (uri.match(re)) {

        return uri.replace(re, '');

    }
}
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.