Как я могу удалить параметр строки запроса в JavaScript? - PullRequest
108 голосов
/ 28 октября 2009

Есть ли лучший способ удалить параметр из строки запроса в строке URL в стандартном JavaScript, кроме использования регулярного выражения?

Вот то, что я до сих пор придумал, что, похоже, работает в моих тестах, но я не люблю заново изобретать синтаксический анализ строки запроса!

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

Ответы [ 19 ]

157 голосов
/ 28 октября 2009
"[&;]?" + 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;
}
22 голосов
/ 04 февраля 2011

Скопировано из ответа 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;
}
18 голосов
/ 16 июня 2017

Современные браузеры предоставляют 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`)
}
16 голосов
/ 09 августа 2014

Я не вижу серьезных проблем с решением регулярных выражений. Но не забудьте сохранить идентификатор фрагмента (текст после #).

Вот мое решение:

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

И, с точки зрения Бобинса, да - вам нужно экранировать . символов в именах параметров.

13 голосов
/ 25 июля 2012

Любой, кто интересуется решением регулярных выражений Я собрал эту функцию, чтобы добавить / удалить / обновить параметр строки запроса. Если значение не указано, параметр будет удален, а параметр добавит / обновит параметр. Если 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;
    }
}

UPDATE

При удалении первого параметра в строке запроса произошла ошибка, я переработал регулярное выражение и проверил, чтобы включить исправление.

ОБНОВЛЕНИЕ 2

@ обновление schellmax для исправления ситуации, когда символ хэштега теряется при удалении переменной строки запроса непосредственно перед хэштегом

7 голосов
/ 04 июля 2018

Вы можете изменить URL с помощью:

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

таким образом, вы можете перезаписать URL без параметра поиска, я использую его для очистки URL после получения параметров GET.

6 голосов
/ 20 марта 2015

Если вы хотите удалить параметр key = val из URI:

function removeParam(uri) {
   return uri.replace(/([&\?]key=val*$|key=val&|[?&]key=val(?=#))/, '');
}
4 голосов
/ 25 мая 2018

Вот что я использую:

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

Оригинальный URL: http://www.example.com/test/hello?id=123&foo=bar
Целевой URL: http://www.example.com/test/hello

4 голосов
/ 17 ноября 2016

Вот полная функция для добавления и удаления параметров, основанная на этом вопросе и этой сути github: 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%, если у этой вещи есть некоторые недостатки, но, насколько я ее протестировал, она работает довольно хорошо.

3 голосов
/ 28 января 2011

Вышеуказанная версия как функция

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