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

除了使用正则表达式,还有其他更好的方法从标准 JavaScript 中 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;
}
299880 次浏览
"[&;]?" + 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;
}

如果你喜欢 jQuery,有一个很好的查询字符串操作插件:

以上版本作为函数

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

从弹跳答案中复制,但使其支持查询字符串中的问号,例如

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

任何对正则表达式解决方案感兴趣的人,我将这个函数放在一起,添加/删除/更新 querystring 参数。不提供值将删除参数,提供值将添加/更新参数。如果没有提供 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;
}
}

更新

在移除 querystring 中的第一个参数时出现了一个 bug,我已经重新编写了 regex,并进行了测试,以包含一个修复程序。

更新2

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

这个线程上的所有响应都有一个缺陷,即它们没有保留 URL 的锚点/片段部分。

因此,如果你的网址看起来像:

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

然后你替换“参数”

你将丢失你的片段文本。

以下是对以前解决这个问题的答案的改编(通过 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;
}

我看不出正则表达式解决方案有什么大问题。但是,不要忘记保留片段标识符(#之后的文本)。

我的解决办法是:

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

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

您应该使用库来执行 URI 操作,因为它比表面上看起来自己执行要复杂得多。看看: http://medialize.github.io/URI.js/

function removeQueryStringParameter(uri, key, value)
{


var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");


var separator = uri.indexOf('?') !== -1 ? "&" : "?";


if (uri.match(re)) {


return uri.replace(re, '');


}
}

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

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

用 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

这将返回 URL w/o ANY GET 参数:

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

下面是一个基于这个问题和 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% 肯定这个东西是否有一些缺陷,但就我所测试的而言,它工作得很好。

在我看来,以上这些都不能处理普通参数和数组参数。

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

当然,要更新一个参数,只需要删除然后添加。

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

现代浏览器 提供了 URLSearchParams接口来处理搜索参数。

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

以下是我正在使用的方法:

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

原始网址: http://www.example.com/test/hello?id=123&foo=bar
目的地网址: < a href = “ http://www.example.com/test/hello”rel = “ nofollow norefrer”> http://www.example.com/test/hello

现在,这个的答案似乎更好! (虽然没有完全测试)

你可以用以下方法更改网址:

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

这样,你就可以在不使用搜索参数的情况下覆盖 URL,我使用它来清除获取 GET 参数后的 URL。

这是一个干净的版本 删除查询参数URL 类为今天的浏览器:

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

旧浏览器不支持 URLSearchParams

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

IE、 Edge (低于17)和 Safari (低于10.3)不支持 URL 类中的 URLSearchParams。

填充物

只有填充物

Https://github.com/webreflection/url-search-params

完成 Polyfill URL 和 URLSearchParams 以匹配最后的 WHATWG 规范

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

这里有一个解决方案:

  1. 使用 < strong > URLSearchParams (不难理解正则表达式)
  2. 更新搜索栏中的 URL 而不重新加载
  3. 维护 URL 的所有其他部分 (例如 hash)
  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);
}
}

注意: 正如在其他答案中指出的,URLSearchParams 是 IE 不支持,因此使用 填料

const params = new URLSearchParams(location.search)
params.delete('key_to_delete')
console.log(params.toString())

我实际上编写了以下函数来处理 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']);


});

我认为这是非常有用的!

另一个直接而简单的答案是

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

很高兴你来了。

我建议你们通过下一个可能的解决办法来解决这项任务:

  1. 您只需要支持现代浏览器(Edge > = 17)-使用 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循环,并且在循环过程中不修改数组
    • 更实用
    • 比 regexp 解决方案更具可读性
    • 在使用之前,请确保您的 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}`}`;
}

看看这里是怎么运作的

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

如果它是 URL的实例,则使用 searchParamsdelete函数

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

如果你有一个 URLSearchParams的填充物,或者不需要支持 Internet Explorer,这就是我在其他答案中建议的方法。如果你不想依赖于 URLSearchParams,我会这么做:

function removeParameterFromUrl(url, parameter) {
const replacer = (m, p1, p2) => (p1 === '?' && p2 === '&' ? '?' : p2 || '')
return url.replace(new RegExp(`([?&])${parameter}=[^&#]+([&#])?`), replacer)
}

它将用 ?替换前面的 ?(p1)和后面的 &(p2)的参数,以确保参数列表仍然以问号开始,否则,它将用下一个分隔符(p2)替换它: 可能是 &,或 #,或 undefined回落到一个空字符串。