Is there better way to delete a parameter from a query string in a URL string in standard JavaScript other than by using a regular expression?
Here's what I've come up with so far which seems to work in my tests, but I don't like to reinvent querystring parsing!
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;
}
This question is related to
javascript
query-string
Glad you scrolled here.
I would suggest you to resolve this task by next possible solutions:
http://google.com/?myparm
http://google.com/?myparm=1
http://google.com?qp=1&qpqp=2&qp=1
for
loop and not modify array during looping over itWorks in IE > 9 (ES5 version)
function removeParamFromUrl(url, param) { // url: string, param: string_x000D_
var urlParts = url.split('?'),_x000D_
preservedQueryParams = '';_x000D_
_x000D_
if (urlParts.length === 2) {_x000D_
preservedQueryParams = urlParts[1]_x000D_
.split('&')_x000D_
.filter(function(queryParam) {_x000D_
return !(queryParam === param || queryParam.indexOf(param + '=') === 0)_x000D_
})_x000D_
.join('&');_x000D_
}_x000D_
_x000D_
return urlParts[0] + (preservedQueryParams && '?' + preservedQueryParams); _x000D_
}
_x000D_
Fancy ES6 version
function removeParamFromUrlEs6(url, param) {_x000D_
const [path, queryParams] = url.split('?');_x000D_
let preservedQueryParams = '';_x000D_
_x000D_
if (queryParams) {_x000D_
preservedQueryParams = queryParams_x000D_
.split('&')_x000D_
.filter(queryParam => !(queryParam === param || queryParam.startsWith(`${param}=`)))_x000D_
.join('&');_x000D_
}_x000D_
_x000D_
return `${path}${preservedQueryParams && `?${preservedQueryParams}`}`; _x000D_
}
_x000D_
If you have a polyfill for URLSearchParams
or simply don't have to support Internet Explorer, that's what I would use like suggested in other answers here. If you don't want to depend on URLSearchParams
, that's how I would do it:
function removeParameterFromUrl(url, parameter) {
const replacer = (m, p1, p2) => (p1 === '?' && p2 === '&' ? '?' : p2 || '')
return url.replace(new RegExp(`([?&])${parameter}=[^&#]+([&#])?`), replacer)
}
It will replace a parameter preceded by ?
(p1
) and followed by &
(p2
) with ?
to make sure the list of parameters still starts with a question mark, otherwise, it will replace it with the next separator (p2
): could be &
, or #
, or undefined
which falls back to an empty string.
Copied from bobince answer, but made it support question marks in the query string, eg
http://www.google.com/search?q=test???+something&aq=f
Is it valid to have more than one question mark in a 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;
}
From what I can see, none of the above can handle normal parameters and array parameters. Here's one that does.
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;
}
}
How to use it:
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
Of course, to update a parameter, just remove then add. Feel free to make a dummy function for it.
A modified version of solution by ssh_imov
function removeParam(uri, keyValue) {
var re = new RegExp("([&\?]"+ keyValue + "*$|" + keyValue + "&|[?&]" + keyValue + "(?=#))", "i");
return uri.replace(re, '');
}
Call like this
removeParam("http://google.com?q=123&q1=234&q2=567", "q1=234");
// returns http://google.com?q=123&q2=567
Assuming you want to remove key=val parameter from URI:
function removeParam(uri) {
return uri.replace(/([&\?]key=val*$|key=val&|[?&]key=val(?=#))/, '');
}
Heres a complete function for adding and removing parameters based on this question and this 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);
};
You can add parameters like this:
updateQueryStringParam( 'myparam', 'true' );
And remove it like this:
updateQueryStringParam( 'myparam', null );
In this thread many said that the regex is probably not the best/stable solution ... so im not 100% sure if this thing has some flaws but as far as i tested it it works pretty fine.
All of the responses on this thread have a flaw in that they do not preserve anchor/fragment parts of URLs.
So if your URL looks like:
http://dns-entry/path?parameter=value#fragment-text
and you replace 'parameter'
you will lose your fragment text.
The following is adaption of previous answers (bobince via LukePH) that addresses this problem:
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;
}
I practically wrote the following function to process the url parameters and get the final status as a string and redirect the page. Hopefully it benefits.
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 '';
}
For example, when I click a button, I want the page value to be deleted and the category value to be added.
let button = document.getElementById('changeCategory');
button.addEventListener('click', function (e) {
window.location = addRemoveUrlQuery({'category':'cars'}, ['page']);
});
I think it was very useful!
I don't see major issues with a regex solution. But, don't forget to preserve the fragment identifier (text after the #
).
Here's my solution:
function RemoveParameterFromUrl(url, parameter) {
return url
.replace(new RegExp('[?&]' + parameter + '=[^&#]*(#.*)?$'), '$1')
.replace(new RegExp('([?&])' + parameter + '=[^&]*&'), '$1');
}
And to bobince's point, yes - you'd need to escape .
characters in parameter names.
If you're into jQuery, there is a good query string manipulation plugin:
You should be using a library to do URI manipulation as it is more complicated than it seems on the surface to do it yourself. Take a look at: http://medialize.github.io/URI.js/
another direct & simpler answer would be
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
const params = new URLSearchParams(location.search)
params.delete('key_to_delete')
console.log(params.toString())
Here a solution that:
?
in query string if the last parameter was removedfunction 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);
}
}
Note: as pointed out in other answers URLSearchParams is not supported in IE, so use a polyfill.
Anyone interested in a regex solution I have put together this function to add/remove/update a querystring parameter. Not supplying a value will remove the parameter, supplying one will add/update the paramter. If no URL is supplied, it will be grabbed from window.location. This solution also takes the url's anchor into consideration.
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
There was a bug when removing the first parameter in the querystring, I have reworked the regex and test to include a fix.
UPDATE 2
@schellmax update to fix situation where hashtag symbol is lost when removing a querystring variable directly before a hashtag
Using 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;
}
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;
}
function removeQueryStringParameter(uri, key, value)
{
var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
var separator = uri.indexOf('?') !== -1 ? "&" : "?";
if (uri.match(re)) {
return uri.replace(re, '');
}
}
The above version as a function
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;
}
Here is what I'm using:
if (location.href.includes('?')) {
history.pushState({}, null, location.href.split('?')[0]);
}
Original URL: http://www.example.com/test/hello?id=123&foo=bar
Destination URL: http://www.example.com/test/hello
This returns the URL w/o ANY GET Parameters:
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 );
}
You can change the URL with:
window.history.pushState({}, document.title, window.location.pathname);
this way, you can overwrite the URL without the search parameter, I use it to clean the URL after take the GET parameters.
Modern browsers provide URLSearchParams
interface to work with search params. Which has delete
method that removes param by name.
if (typeof URLSearchParams !== 'undefined') {_x000D_
const params = new URLSearchParams('param1=1¶m2=2¶m3=3')_x000D_
_x000D_
console.log(params.toString())_x000D_
_x000D_
params.delete('param2')_x000D_
_x000D_
console.log(params.toString())_x000D_
_x000D_
} else {_x000D_
console.log(`Your browser ${navigator.appVersion} does not support URLSearchParams`)_x000D_
}
_x000D_
If it's an instance of URL
, use the delete
function of searchParams
let url = new URL(location.href);
url.searchParams.delete('page');
This is a clean version remove query parameter with the URL class for today browsers:
function removeUrlParameter(url, paramKey)
{
var r = new URL(url);
r.searchParams.delete(paramKey);
return r.href;
}
URLSearchParams not supported on old browsers
https://caniuse.com/#feat=urlsearchparams
IE, Edge (below 17) and Safari (below 10.3) do not support URLSearchParams inside URL class.
Polyfills
URLSearchParams only polyfill
https://github.com/WebReflection/url-search-params
Complete Polyfill URL and URLSearchParams to match last WHATWG specifications
Source: Stackoverflow.com