Bagaimana saya bisa menghapus parameter string kueri dalam JavaScript?


127

Apakah ada cara yang lebih baik untuk menghapus parameter dari string kueri dalam string URL dalam JavaScript standar selain dengan menggunakan ekspresi reguler?

Inilah yang saya buat sejauh ini yang tampaknya berhasil dalam tes saya, tetapi saya tidak suka menemukan parsing 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;
}

Jawaban:


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

Tampaknya berbahaya karena parameter 'bar' akan cocok:

?a=b&foobar=c

Juga, itu akan gagal jika parameterberisi karakter yang khusus di RegExp, seperti '.' Dan itu bukan regex global, jadi itu hanya akan menghapus satu instance dari parameter.

Saya tidak akan menggunakan RegExp sederhana untuk ini, saya akan mengurai parameter dan kehilangan yang tidak Anda inginkan.

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

Poin bagus tentang bilah yang cocok dengan foobar. Saya telah memperbarui regex asli saya untuk meminta? atau [&;] di awal. Juga membaca solusi Anda untuk mempertimbangkannya ...
Matthew Lock

5
Jika Anda ingin menyingkirkan "?" ketika tidak ada parameter setelah penghapusan, tambahkan kondisi jika untuk menguji jika pars.length == 0, dan jika 0, maka buatlah "url = urlparts [0]" alih-alih menambahkan "?".
johnmcaliley

2
Apakah aman untuk membandingkan fragmen URL dengan komponen encodeURICon (parameter)? Bagaimana jika URL menyandikan nama parameter secara berbeda? Misalnya 'dua% 20 kata' versus 'dua + kata'. Untuk mengatasinya, mungkin lebih baik men-decode nama parameter dan membandingkannya dengan string normal.
Adrian Pronk

9
Perbaikan ringan, sehingga ketika Parameter URL final dihapus, '?' akan dihapus juga: Ubah jalur url= urlparts[0]+'?'+pars.join('&');keurl= urlparts[0] + (pars.length > 0 ? '?' + pars.join('&') : "");
Cody S

2
@ ktutnik / @ JonasAxelsson parameter permintaan URL secara alami tidak peka terhadap huruf besar-kecil.
bobince

30

Browser modern menyediakan URLSearchParamsantarmuka untuk bekerja dengan params pencarian. Yang memiliki deletemetode yang menghapus param dengan nama.

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
Catatan yang URLSearchParamstidak didukung oleh IE, Edge 16 dan iOS 10.2 Safari. (ref: caniuse.com/#feat=urlsearchparams )
khiav reoy

3
@khiavreoy Ya. Seperti dua kata pertama dalam jawaban berikan tautan yang sama :)
Yury Tarabanko

23

Disalin dari jawaban bobince, tetapi membuatnya mendukung tanda tanya di string kueri, mis

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

Apakah valid untuk memiliki lebih dari satu tanda tanya di 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
Saya percaya ???ini adalah sintaks yang tidak valid dan seharusnya tidak pernah muncul di URL`.

@torazaburo Lihat pertanyaan stackoverflow yang saya posting: "Apakah valid untuk memiliki lebih dari satu tanda tanya di URL?", jawabannya tampaknya ya. Juga ini bertahun-tahun lalu jadi saya tidak dapat mengingat detailnya tetapi saya mengalami masalah ketika ini tidak ditangani dengan benar.
LukePH

Saya tidak mengatakan mereka tidak ada di dunia nyata, dan orang mungkin ingin bisa menanganinya, tetapi dalam URL yang dibentuk dengan benar, tanda tanya adalah "karakter yang dilindungi" dan tanda tanya apa pun selain yang memperkenalkan parameter kueri harus dikodekan URL.

1
Anda mungkin ingin mengganti baris terakhir dengan return url.endsWith("?") ? url.slice(0,-1) : url;untuk menutupi kasus di mana parameter yang akan dihapus adalah satu-satunya di string kueri
Konamiman

@Konamiman Itu akan mengubah data parameter ketika misalnya menghapus 'aq' dari: google.com/search?q=test???&aq=f tapi saya mengerti maksud Anda, akan lebih baik untuk membersihkan url meskipun jika ? tidak membahayakan. Logikanya hanya perlu memastikan yang terakhir? juga yang pertama?
LukePH

21

Saya tidak melihat masalah besar dengan solusi regex. Tapi, jangan lupa untuk menyimpan pengidentifikasi fragmen (teks setelah #).

Inilah solusi saya:

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

Dan untuk poin bobince, ya - Anda harus melarikan diri .karakter dalam nama parameter.


1
Berikut ini adalah regex yang disempurnakan yang berfungsi saat paramater tidak memiliki nilai (yaitu 'ex.com?removeMe'), dan tidak akan mengganti parameter dalam fragmen (yaitu 'ex.com?#&dont=removeMe') atau jalur (yaitu ' ex.com/&dont=removeMe '):url.replace(new RegExp('^([^#]*\?)(([^#]*)&)?' + parameter + '(\=[^&#]*)?(&|#|$)' ), '$1$3$5').replace(/^([^#]*)((\?)&|\?(#|$))/,'$1$3$4')
Stephen M. Harris

Ini tidak akan berhasil Stephen M. Harris. Cobalah untuk memberikan kode Anda sebuah String kosong sebagai param dan lihat apa yang terjadi ...
David Fischer

15

Anda dapat mengubah URL dengan:

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

dengan cara ini, Anda dapat menimpa URL tanpa parameter pencarian, saya menggunakannya untuk membersihkan URL setelah mengambil parameter GET.


13

Siapa pun yang tertarik pada solusi regex Saya telah mengumpulkan fungsi ini untuk menambah / menghapus / memperbarui parameter querystring. Tidak memberikan nilai akan menghapus parameter, memasok satu akan menambah / memperbarui paramter. Jika tidak ada URL yang diberikan, itu akan diambil dari window.location. Solusi ini juga mempertimbangkan jangkar 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;
    }
}

MEMPERBARUI

Ada bug ketika menghapus parameter pertama dalam querystring, saya telah mengerjakan ulang regex dan tes untuk menyertakan perbaikan.

PEMBARUAN 2

Pembaruan @schellmax untuk memperbaiki situasi di mana simbol tagar hilang ketika menghapus variabel querystring langsung sebelum tagar


1
Ini tidak berfungsi jika Anda memiliki dua string kueri dan menghapus yang pertama. URL yang diteruskan menjadi tidak valid karena? dihapus ketika harus dilestarikan.
Blake Niemyjski

1
@BlakeNiemyjski terima kasih telah menemukan bug itu, saya telah memperbarui skrip untuk menyertakan solusi untuk parameter pertama
ellemayo

1
akan secara tidak sengaja menghapus hash di sini:UpdateQueryString('a', null, 'http://www.test.com?a=b#c');
schellmax

Fungsi keren, terima kasih. FYI: saat menggunakan ini dengan kunci array abaikan di setiap loop () `, Anda mungkin perlu menentukan penyusutan yang selalu urluntuk setiap iterasi penggantian. Tapi, itu berarti Anda harus memasukkan valueargumen, yang akan membuat setengah querystring dihapus. Untuk mengatasi ini, gunakan undefinedatau nulluntuk valueargumen seperti:url_from_last_iteration = UpdateQueryString(current_ignore_key, undefined/null, url_from_last_iteration);
dhaupin

7

Dengan asumsi Anda ingin menghapus key = val parameter dari URI:

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

Bekerja dengan baik tetapi lolos dari tanda tanya pertama di regex tidak perlu dan dapat menyebabkan kesalahan linter: /([&?]key=val*$|key=val&|[?&]key=val(?=#))/mungkin lebih disukai ketika menggunakan linter seperti eslint
quetzaluz


6

Inilah fungsi lengkap untuk menambah dan menghapus parameter berdasarkan pertanyaan ini dan inti github ini: 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);
};

Anda dapat menambahkan parameter seperti ini:

updateQueryStringParam( 'myparam', 'true' );

Dan hapus seperti ini:

updateQueryStringParam( 'myparam', null );

Di utas ini banyak yang mengatakan bahwa regex mungkin bukan solusi terbaik / stabil ... jadi saya tidak 100% yakin jika hal ini memiliki beberapa kekurangan tetapi sejauh yang saya uji itu berfungsi cukup baik.


5

Ini adalah versi bersih menghapus parameter kueri dengan kelas URL untuk browser hari ini:

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

URLSearchParams tidak didukung di browser lama

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

IE, Edge (di bawah 17) dan Safari (di bawah 10.3) tidak mendukung URLSearchParams di dalam kelas URL.

Polyfill

URLSearchParams hanya polyfill

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

Lengkapi URL Polyfill dan URLSearchParams agar sesuai dengan spesifikasi WHATWG terakhir

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


4

Menggunakan 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

Versi di atas sebagai fungsi

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

Dari apa yang saya lihat, tidak ada yang di atas dapat menangani parameter normal dan parameter array. Inilah yang melakukannya.

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

Bagaimana cara menggunakannya:

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

Tentu saja, untuk memperbarui parameter, hapus saja lalu tambahkan. Jangan ragu untuk membuat fungsi dummy untuk itu.


path.replace(new RegExp("&?"+param+"=[\\w]+", "g"), "");Saya akan mengubah regex [\\w]*untuk memasukkan parameter seperti "param =" tanpa nilai.
Tomas Prado

2

Semua tanggapan di utas ini memiliki kelemahan karena tidak mempertahankan bagian-bagian URL yang tidak berlabuh / terpotong-potong.

Jadi jika URL Anda terlihat seperti:

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

dan Anda mengganti 'parameter'

Anda akan kehilangan teks fragmen Anda.

Berikut ini adalah adaptasi dari jawaban sebelumnya (bobince via LukePH) yang mengatasi masalah ini:

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
Perbaikan ringan, sehingga ketika Parameter URL final dihapus, '?' akan dihapus juga: Ubah jalur url = urlBase+'?'+pars.join('&');keurl = urlBase + (pars.length > 0 ? '?' + pars.join('&') : "");
Cody S


2

Berikut solusi yang:

  1. menggunakan URLSearchParams (tidak sulit untuk memahami regex)
  2. memperbarui URL di bilah pencarian tanpa memuat ulang
  3. memelihara semua bagian lain dari URL (mis. hash)
  4. menghapus superflous? dalam string kueri jika parameter terakhir dihapus
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);
    }
}

Catatan: seperti yang ditunjukkan dalam jawaban lain, URLSearchParams tidak didukung di IE , jadi gunakan polyfill .


2

Jika ini adalah contoh dari URL, gunakan deletefungsisearchParams

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

1

jawaban langsung & sederhana lainnya adalah

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

Versi solusi yang dimodifikasi oleh ssh_imov

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

Panggil seperti ini

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

satu hal yang perlu diingat ketika mengirim nilai param convert space ke% 20
xeon zolt

0

Ini mengembalikan URL tanpa Parameter APA PUN:

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

Saya praktis menulis fungsi berikut untuk memproses parameter url dan mendapatkan status akhir sebagai string dan mengarahkan ulang halaman. Semoga bermanfaat.

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

Misalnya, ketika saya mengklik tombol, saya ingin nilai halaman dihapus dan nilai kategori ditambahkan.

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

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

});

Saya pikir itu sangat berguna!


0

Senang Anda menggulir di sini.

Saya menyarankan Anda untuk menyelesaikan tugas ini dengan solusi yang mungkin berikutnya:

  1. Anda hanya perlu mendukung browser modern (Edge> = 17) - gunakan URLSearchParams.delete () API . Ini asli dan jelas merupakan cara paling mudah untuk menyelesaikan tugas ini.
  2. Jika ini bukan opsi, Anda mungkin ingin menulis fungsi untuk melakukan ini. Fungsi seperti itu itu
    • jangan ubah URL jika parameter tidak ada
    • hapus parameter URL tanpa nilai, seperti http://google.com/?myparm
    • hapus parameter URL dengan nilai, seperti http://google.com/?myparm=1
    • hapus parameter URL jika ada di URL dua kali, seperti http://google.com?qp=1&qpqp=2&qp=1
    • Tidak digunakan for loop dan tidak mengubah array selama pengulangan di atasnya
    • lebih fungsional
    • lebih mudah dibaca daripada solusi regexp
    • Sebelum menggunakan pastikan URL Anda tidak dikodekan

Bekerja di IE> 9 (versi 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); 
}

Versi ES6 mewah

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

Lihat cara kerjanya di sini


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())

Ini adalah jawaban untuk pertanyaan yang sudah sangat lama dan sudah memiliki jawaban yang diterima. Tolong jelaskan apa yang ditawarkan jawaban ini yang baru / berbeda dari jawaban lainnya. Selain itu, jawaban harus mencakup penjelasan dan bukan hanya kode.
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, '');

    }
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.