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

Mat*_*ock 115 javascript query-string

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

这是我到目前为止所提出的,似乎在我的测试中有效,但我不喜欢重新发明查询字符串解析!

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;
}
Run Code Online (Sandbox Code Playgroud)

bob*_*nce 169

"[&;]?" + parameter + "=[^&;]+"
Run Code Online (Sandbox Code Playgroud)

似乎很危险,因为参数'bar'会匹配:

?a=b&foobar=c
Run Code Online (Sandbox Code Playgroud)

此外,如果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;
}
Run Code Online (Sandbox Code Playgroud)

  • 温和改进,以便在删除最终的URL参数时,'?' 也被删除:将行`url = urlparts [0] +'?'+ pars.join('&');`更改为`url = urlparts [0] +(pars.length> 0?'?'+ pars .join('&'):"");` (9认同)
  • 如果你想摆脱"?" 当删除后没有参数时,添加一个if条件来测试pars.length == 0,如果它是0,那么make"url = urlparts [0]"而不是附加"?". (5认同)
  • 不处理哈希. (2认同)
  • 比较URL片段和encodeURIComponent(parameter)是否安全?如果URL对参数名称的编码不同,该怎么办?例如,“ two%20words”与“ two + words”。为了解决这个问题,最好对参数名称进行解码并将其与普通字符串进行比较。 (2认同)
  • @ ktutnik / @ JonasAxelsson URL查询参数自然不区分大小写。 (2认同)

小智 22

从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;
}
Run Code Online (Sandbox Code Playgroud)

  • 我相信`???`是无效的语法,并且永远不会出现在URL中。 (2认同)

Yur*_*nko 21

现代浏览器提供URLSearchParams了与搜索参数一起使用的界面.哪个delete方法可以按名称删除param.

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`)
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,IE、Edge 16 和 iOS 10.2 Safari 不支持“URLSearchParams”。(参考:https://caniuse.com/#feat=urlsearchparams) (2认同)
  • @khiavreoy是的 就像答案中的前两个单词给出相同的链接:) (2认同)
  • 如果您使用完整的 URL 而不是仅包含参数的字符串,则可以使用“URL”构造函数的“searchParams.delete”。请参阅此答案:/sf/answers/4341588331/ (2认同)

小智 20

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

这是我的解决方案:

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

对于bobince的观点,是的 - 您需要.在参数名称中转义字符.


ell*_*ayo 13

任何对正则表达式解决方案感兴趣的人都把这个函数放在一起来添加/删除/更新查询字符串参数.不提供值将删除参数,提供一个将添加/更新参数.如果没有提供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;
    }
}
Run Code Online (Sandbox Code Playgroud)

UPDATE

删除查询字符串中的第一个参数时出现错误,我重新编写了正则表达式并测试了包含修复.

更新2

@schellmax更新以修复在hashtag之前直接删除querystring变量时hashtag符号丢失的情况


War*_*red 11

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

let url = new URL(location.href);
url.searchParams.delete('page');
Run Code Online (Sandbox Code Playgroud)


San*_*nez 9

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

window.history.pushState({}, document.title, window.location.pathname);
Run Code Online (Sandbox Code Playgroud)

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

  • 如果只有一个搜索参数需要删除而不更改其他搜索参数怎么办?谢谢! (4认同)

小智 7

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

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


GDY*_*GDY 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);
};
Run Code Online (Sandbox Code Playgroud)

您可以添加如下参数:

updateQueryStringParam( 'myparam', 'true' );
Run Code Online (Sandbox Code Playgroud)

然后像这样删除它:

updateQueryStringParam( 'myparam', null );
Run Code Online (Sandbox Code Playgroud)

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


Bas*_*asj 6

这是我正在使用的:

if (location.href.includes('?')) { 
    history.pushState({}, null, location.href.split('?')[0]); 
}
Run Code Online (Sandbox Code Playgroud)

原始网址:http
: //www.example.com/test/hello?id = 123&foo = bar目标网址:http : //www.example.com/test/hello


Her*_*him 6

这是当今浏览器的带有URL 类的干净版本删除查询参数

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

旧浏览器不支持 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


klu*_*ues 6

这里有一个解决方案:

  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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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