Як я можу видалити параметр рядка запиту в JavaScript?


127

Чи є кращий спосіб видалити параметр із рядка запиту в рядку 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;
}

Відповіді:


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

Хороший момент про планку, що відповідає фубар. Я оновив свій оригінальний регулярний вираз, щоб вимагати? або [&;] на початку. Також читайте ваше рішення, щоб розглянути це ...
Метью Блокування

5
Якщо ви хочете позбутися від "?" коли після видалення немає параметрів, додайте умову if, щоб перевірити, чи pars.length == 0, а якщо це 0, то зробіть "url = urlparts [0]" замість додавання "?".
johnmcaliley

2
Чи безпечно порівнювати фрагмент URL-адреси з encodeURIComponent (параметром)? Що робити, якщо URL кодує ім'я параметра по-іншому? Наприклад, "два% 20 слів" проти "два + слова". Для вирішення цього питання, можливо, буде краще розшифрувати ім'я параметра і порівняти його як звичайний рядок.
Адріан Пронк

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 Так. Як і перші два слова у відповіді дають те саме посилання :)
Юрій Тарабанко

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-адресі?", як видається, відповідь "так". Також це було років тому, тому я не можу згадати подробиці, але я зіткнувся з проблемами, коли це було неправильно вирішено.
ЛукPH

Я не кажу, що їх не існує в реальному світі, і, напевно, можна було б мати можливість поводитися з ними, але в правильно сформованій URL-адресі знак питання - це "зарезервований символ" і будь-який знак питання, окрім одного введення параметрів запиту має бути кодованим URL-адресою.

1
Ви можете замінити останній рядок на, return url.endsWith("?") ? url.slice(0,-1) : url;щоб висвітлити випадок, коли параметр, який потрібно видалити, є єдиним у рядку запиту
Konamiman

@Konamiman Це міняло б дані параметрів, наприклад, видаляючи "aq" з: google.com/search?q=test???&aq=f, але я розумію, що ви маєте на увазі, було б непогано очистити URL, навіть якщо ? не шкодить. Логіці просто потрібно переконатися в останньому? теж перший ?.
ЛукPH

21

Я не бачу великих проблем з рішенням регулярного виразів. Але не забудьте зберегти ідентифікатор фрагмента (текст після цього #).

Ось моє рішення:

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

І до точки bobince, так - вам потрібно буде уникати .символів у назвах параметрів.


1
Ось вдосконалений регулярний вираз, який працює, коли параметр не має значення (тобто 'ex.com?removeMe'), і не замінить параметр у фрагментах (тобто 'ex.com?#&dont=removeMe') або шляхах (тобто ' ex.com/&dont=removeMe '):url.replace(new RegExp('^([^#]*\?)(([^#]*)&)?' + parameter + '(\=[^&#]*)?(&|#|$)' ), '$1$3$5').replace(/^([^#]*)((\?)&|\?(#|$))/,'$1$3$4')
Стівен М. Харріс

Це не спрацює Стівен М. Харріс. Спробуйте дати коду порожній рядок як парам і побачити, що станеться ...
Девід Фішер,

15

Ви можете змінити URL-адресу за допомогою:

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

таким чином, ви можете перезаписати URL без параметра пошуку, я використовую його для очищення URL-адреси після прийняття параметрів GET.


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

ОНОВЛЕННЯ

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

ОНОВЛЕННЯ 2

Оновлення @schellmax, щоб виправити ситуацію, коли символ хештегу втрачається під час видалення змінної запиту безпосередньо перед хештегом


1
Це не працює, якщо у вас є два рядки запиту та видаліть перший. Передане в URL-адресі стає недійсним, оскільки? видаляється тоді, коли його слід зберегти.
Блейк Ніємійський

1
@BlakeNiemyjski дякую, що знайшов цю помилку, я оновив сценарій, щоб включити вирішення першого параметра
ellemayo

1
випадково видалить хеш сюди:UpdateQueryString('a', null, 'http://www.test.com?a=b#c');
schellmax

Класна функція, дякую. FYI: використовуючи це з клавішами ігнорування масиву в кожній циклі () `, вам може знадобитися визначити постійно зменшується urlдля кожної ітерації заміни. Але це означає, що ви повинні ввести valueаргумент, який залишить половину запиту видаленою. Щоб протистояти цьому, використовуйте undefinedабо nullдля valueаргументу на зразок:url_from_last_iteration = UpdateQueryString(current_ignore_key, undefined/null, url_from_last_iteration);
dhaupin

7

Припустимо, що ви хочете видалити параметр key = val з URI:

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

Добре працює, але уникнення першого знака питання в регулярному вираженні не є зайвим і може спричинити помилку лінійки: /([&?]key=val*$|key=val&|[?&]key=val(?=#))/може бути кращим при використанні вкладиша на зразок eslint
quetzaluz

7

Ось що я використовую:

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


Ви пишете цей код при завантаженні сторінки? Я прошу вас, тому що коли я пишу це завантаження сторінки чи ні, це не працює.
noobprogrammer

6

Ось повна функція додавання та видалення параметрів на основі цього питання та цього github gistub: 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 для сьогоднішніх браузерів:

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

URL-ПошукПарами не підтримуються у старих браузерах

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

IE, Edge (нижче 17) та Safari (нижче 10.3) не підтримують URLSearchParams всередині класу URL.

Поліфузи

URLSearchParams тільки для заповнення

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

Повна URL-адреса Polyfill та 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 =" без значень.
Томаш Прадо

2

Усі відповіді на цю тему мають недолік у тому, що вони не зберігають якірні / фрагментарні частини URL-адрес.

Отже, якщо ваша URL-адреса виглядає так:

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

і ви замінюєте "параметр"

ви втратите текст фрагмента.

Далі йде адаптація попередніх відповідей (bobince через 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

що робити, якщо # виходить першим? dns-entry / path # fragment-text? parameter = value
ajayv

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

Примітка: як зазначено в інших відповідях, URL-пошукParams не підтримується в IE , тому використовуйте полізаполнення .


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

Це повертає 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, якщо параметр відсутній
    • видалити параметр URL без значення, наприклад http://google.com/?myparm
    • видаліть параметр URL зі значенням, наприклад http://google.com/?myparm=1
    • видаліть параметр URL, якщо він є в URL-адресі двічі, наприклад http://google.com?qp=1&qpqp=2&qp=1
    • Не використовує for цикл і не змінює масив під час циклу за ним
    • є більш функціональним
    • є більш читабельним, ніж рішення для регулярного вирівнювання
    • Перед використанням переконайтеся, що ваша URL-адреса не закодована

Працює в 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())

Це відповідь на запитання, яке дуже давно і вже має прийняту відповідь. Поясніть, будь ласка, що може запропонувати відповідь, що є новим / відмінним від інших відповідей. Також відповіді повинні містити пояснення, а не лише код.
медсестра

-2

Якщо ви користуєтесь jQuery, є хороший плагін для маніпуляції з рядком запиту:


1
Перша з цих ланок мертва; альтернатива: github.com/fadhlirahim/jqURL .
Мартін Карпентер

Спасибі, вилучено - через пару років він повинен був стати несвіжим! :)
Дамовіса

-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, '');

    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.