如何使用Javascript/jQuery添加或替换URL中的查询参数?

10

我正在使用 jQuery 1.12。我想要替换窗口URL查询字符串中的一个查询参数,如果不存在,则添加该参数。 我尝试了以下内容:

new_url = window.location.href.replace( /[\?#].*|$/, "?order_by=" + data_val )  
window.location.href = new_url 

但我发现这会清除查询字符串中的所有先前参数,而我不想要这样。如果查询字符串为:

?a=1&b=2

我希望新的查询字符串为:

?a=2&b=2&order_by=data

如果查询字符串是:

?a=2&b=3&order_by=old_data

它将变成:

?a=2&b=3&order_by=data

只是想知道...你期望一个“替换”函数应该做什么? - Lelio Faieta
请查看这个问题:https://dev59.com/QW025IYBdhLWcg3wclq- - dodov
在这种情况下,您需要检查旧查询参数、新查询参数和新查询参数值是否为空或无效(例如错误的旧查询参数)。此外,您还需要检查当前URL是否有任何查询参数。这些通常是您的“添加或替换”查询参数函数中需要执行的检查。 - user2560539
11个回答

5
一个好的解决方案应该处理以下所有内容:
  1. 已经有一个带有order_by查询参数的URL,可选地在等号之前加上空格。这可以进一步分为查询字符串开头、中间或结尾出现order_by的情况。
  2. 没有order_by查询参数但已经有一个问号来分隔查询字符串的URL。
  3. 没有order_by查询参数且没有问号来分隔查询字符串的URL。
下面将处理以上情况:
  if (/[?&]order_by\s*=/.test(oldUrl)) {
    newUrl = oldUrl.replace(/(?:([?&])order_by\s*=[^?&]*)/, "$1order_by=" + data_val);
  } else if (/\?/.test(oldUrl)) {
    newUrl = oldUrl + "&order_by=" + data_val;
  } else {
    newUrl = oldUrl + "?order_by=" + data_val;
  }

如下所示:

getNewUrl("?a=1&b=2");
getNewUrl("?a=2&b=3&order_by=old_data");
getNewUrl("?a=2&b=3&order_by = old_data&c=4");
getNewUrl("?order_by=old_data&a=2&b=3");
getNewUrl("http://www.stackoverflow.com");

function getNewUrl(oldUrl) {
  var data_val = "new_data";
  var newUrl;
  if (/[?&]order_by\s*=/.test(oldUrl)) {
    newUrl = oldUrl.replace(/(?:([?&])order_by\s*=[^?&]*)/, "$1order_by=" + data_val);
  } else if (/\?/.test(oldUrl)) {
    newUrl = oldUrl + "&order_by=" + data_val;
  } else {
    newUrl = oldUrl + "?order_by=" + data_val;
  }
  console.log(oldUrl + "\n...becomes...\n" + newUrl);
}  


很好,除非在URL中有一个#anchor。 - JLuc

5
您可以使用jQuery插件为您完成所有繁重的工作。它会解析查询字符串,并为您重建更新后的查询字符串。要处理的代码要少得多。 插件下载页面 Github仓库
// URL: ?a=2&b=3&order_by=old_data

var order_by = $.query.get('order_by');
//=> old_data

// Conditionally modify parameter value
if (order_by) { 
  order_by = 'data';
}

// Inject modified parameter back into query string
var newUrl = $.query.set('order_by', order_by).toString();
//=> ?a=2&b=3&order_by=data

对于使用Node.js的人来说,可以在NPM中找到这个包。

NPM包
Github仓库

var queryString = require('query-string');
var parsed = queryString.parse('?a=2&b=3&order_by=old_data');  // location.search

// Conditionally modify parameter value
if (parsed.order_by) {
  parsed.order_by = 'data';
}

// Inject modified parameter back into query string
const newQueryString = queryString.stringify(parsed);
//=> a=2&b=3&order_by=data

我正在使用jQuery(1.12)。jQuery是否有与此相关的插件? - user7055375
有一些jQuery插件可以完成同样的工作。你可以在这里下载一个:https://plugins.jquery.com/query-object/. 此页面上的“阅读文档”链接将指向GitHub存储库,其中有大量关于解析和操作查询字符串的示例。如果满足需求,请告诉我,我将修改我的答案。 - grizzthedj
我更新了我的答案,包括关于jQuery插件选项的信息。 - grizzthedj

4

something like this?

let new_url = "";

if (window.location.search && window.location.search.indexOf('order_by=') != -1) {
  new_url = window.location.search.replace( /order_by=\w*\d*/, "order_by=" + data_val);
} else if (window.location.search) {
  new_url = window.location.search + "&order_by=" + data_val;
} else {
  new_url = window.location.search + "?order_by=" + data_val;
}
window.location.href = new_url;

嗨,这个不起作用。如果查询字符串是“?a=1&b=2&order_by=whatever”,而我想把它变成“?a=1&b=2&order_by=new_data”,那么上面的结果就是“?a=1&b=2&order_by=whatever&order_by=new_data”。 - user7055375
1
这仍然不起作用。如果查询字符串不包含“order_by”,则通过调用上面的代码永远不会添加它。 - user7055375
@Natalia,你是对的,我添加了条件,新代码在上面。 - Georgiy Dubrov
谢谢。有没有办法将这个缩短成一两行?这看起来相当长。 - user7055375
无论如何,现有的代码行都不起作用。如果查询字符串是"a&order_by=abc%20desc",那么order_by参数不会被替换。我认为我们应该放弃这个问题。 - user7055375
@Natalia 不会,因为在替换条件的正则表达式中只包含数字和字符串字符,不包括特殊字符如%或_。 - Georgiy Dubrov

3

function addOrReplaceOrderBy(newData) {
  var stringToAdd = "order_by=" + newData;

  if (window.location.search == "")
    return window.location.href + stringToAdd;

  if (window.location.search.indexOf('order_by=') == -1)
    return window.location.href + stringToAdd;

  var newSearchString = "";
  var searchParams = window.location.search.substring(1).split("&");
  for (var i = 0; i < searchParams.length; i++) {
    if (searchParams[i].indexOf('order_by=') > -1) {
      searchParams[i] = "order_by=" + newData;
      break;
    }
  }
  return window.location.href.split("?")[0] + "?" + searchParams.join("&");
}

window.location.href = addOrReplaceOrderBy("new_order_by");

有点长,但我认为它的作用是有效的。


2
你可以使用 URLSearchParams 来从查询字符串中删除参数 https://developer.mozilla.org/ru/docs/Web/API/URLSearchParams?param11=val。但这种方法还不支持 IE 和 Safari,请使用 polyfill https://github.com/jerrybendy/url-search-params-polyfill
访问或修改 URI 的查询部分,应该使用 window.location 的 "search" 属性。
以下是工作代码示例:

  var a = document.createElement("a")
  a.href = "http://localhost.com?param1=val&param2=val2&param3=val3#myHashCode";
  var queryParams = new URLSearchParams(a.search)
  queryParams.delete("param2")
  a.search = queryParams.toString();
  console.log(a.href);


1

试试这个:

For reading parameters:

const data = ['example.com?var1=value1&var2=value2&var3=value3', 'example.com?a=2&b=2&order_by=data']

const getParameters = url => {
  const parameters = url.split('?')[1],
        regex = /(\w+)=(\w+)/g,
        obj = {}
  let temp
  while (temp = regex.exec(parameters)){
    obj[temp[1]] = decodeURIComponent(temp[2])
  }
  return obj
}

for(let url of data){
  console.log(getParameters(url))
}

仅用于放置这些参数:

const data = ['example.com?zzz=asd']
const parameters = {a:1, b:2, add: "abs"}

const setParameters = (url, parameters) => {
  const keys = Object.keys(parameters)
  let temp = url.split('?')[0] += '?'
  for (let i = 0; i < keys.length; i++) {
    temp += `${keys[i]}=${parameters[keys[i]]}${i  == keys.length - 1 ? '' : '&'}`
  }
  return temp
}

for (let url of data){
  console.log(setParameters(url, parameters))
}

最后是插入(或替换已存在的内容)的方法。

const data = ['example.com?a=123&b=3&sum=126']
const parameters = {order_by: 'abc', a: 11}
const insertParameters = (url, parameters) => {
  const keys = Object.keys(parameters)
  let result = url
  for (let i = 0; i < keys.length; i++){
    if (result.indexOf(keys[i]) === -1) {
      result += `&${keys[i]}=${encodeURIComponent(parameters[keys[i]])}`
    } else {
      let regex = new RegExp(`${keys[i]}=(\\w+)`)
      result = result.replace(regex, `&${keys[i]}=${encodeURIComponent(parameters[keys[i]])}`)
    }
  }
  return result
}

for (let url of data){
  console.log(insertParameters(url, parameters))
}

希望这对你有用;)使用函数后,只需替换window.location.href

1
这个小函数可能会有所帮助。

function changeSearchQueryParameter(oldParameter,newParameter,newValue) {
var parameters = location.search.replace("?", "").split("&").filter(function(el){ return el !== "" });
var out = "";
var count = 0;
if(oldParameter.length>0) {
if(newParameter.length>0 && (newValue.length>0 || newValue>=0)){
 out += "?";
 var params = [];
 parameters.forEach(function(v){
  var vA = v.split("=");
  if(vA[0]==oldParameter) {
   vA[0]=newParameter;
   if((newValue.length>0 || newValue>=0)) {
   vA[1] = newValue;   
   }
  } else {
   count++;
  }
  params.push(vA.join("=")); 
 });
 if(count==parameters.length) {
  params.push([newParameter,newValue].join("="));
 }
  params = params.filter(function(el){ return el !== "" });
  if(params.length>1) {
  out += params.join("&");
  } 
  if(params.length==1) {
  out += params[0];
  } 
 }
} else {
if((newParameter.length>0) && (newValue.length>0 || newValue>=0)){
if(location.href.indexOf("?")!==-1) {
var out = "&"+newParameter+"="+newValue; 
} else {
var out = "?"+newParameter+"="+newValue; 
}
}
}
return location.href+out;
}
// if old query parameter is declared but does not exist in url then new parameter and value is simply added if it exists it will be replaced
console.log(changeSearchQueryParameter("ib","idx",5));
// add new parameter and value in url
console.log(changeSearchQueryParameter("","idy",5));
// if no new or old parameter are present url does not change
console.log(changeSearchQueryParameter("","",5));
console.log(changeSearchQueryParameter("","",""));


1
使用正则表达式模式,我更喜欢这个:

var oldUrl = "http://stackoverflow.com/";
var data_val = "newORDER" ;
var r = /^(.+order_by=).+?(&|$)(.*)$/i ;
var newUrl = "";

var matches = oldUrl.match(r) ;
if(matches===null){
  newUrl = oldUrl + ((oldUrl.indexOf("?")>-1)?"&":"?") + "order_by=" + data_val ;
}else{
  newUrl = matches[1]+data_val+matches[2]+matches[3] ;
}
conole.log(newUrl);

如果不存在 order_bymatchesnullorder_by=.. 应该出现在 ?& 之后(如果存在其他参数,则新的参数需要使用 &)。
如果存在 order_bymatches 包含3个项目,请参见此处

1
也许您可以尝试调整正则表达式,以仅检索您要查找的值,然后在帮助函数中添加或更新它们,类似于以下内容:
function paramUpdate(param) {

  var url = window.location.href,
      regExp = new RegExp(param.key + '=([a-z0-9\-\_]+)(?:&)?'),
      existsMatch = url.match(regExp);

  if (!existsMatch) {
      return url + '&' + param.key + '=' + param.value
  }

  var paramToUpdate = existsMatch[0],
      valueToReplace = existsMatch[1],
      updatedParam = paramToUpdate.replace(valueToReplace, param.value);

  return url.replace(paramToUpdate, updatedParam);
}

var new_url = paramUpdate({
    key: 'order_by',
    value: 'id'
});
window.location.href = new_url;

希望它能满足您的需求!

0

function myFunction() {
  var str = "https://www.citicards.com/cards/credit/application/flow.action?app=UNSOL&HKOP=828cca70910b4fe25e118bd0b59b89c3c7c560df877909495d8252d20026cf8d&cmp=afa|acquire|2003|comparecards&ranMID=44660&ranEAID=2759285&ProspectID=516511657A844EF3A6F0C2B1E85FEFB0&ID=3000";
  var res = str.split("&");
  var myKey;
  if (!str.includes("ranSiteID")) {

    console.log("key not found ");
    res.push('ranSiteID=samplearsdyfguh.090-nuvbknlmc0.gvyhbjknl')
    console.log(res.join("&"));

  } else {

    res.map(function(key) {
      console.log("my keys", key);

      if (key.includes("ranSiteID")) {
        console.log("my required-->key", key);
        mykey = key.split("=");
        console.log(mykey);

      }
    })
  }

  document.getElementById("demo").innerHTML = res;
}
<!DOCTYPE html>
<html>

<body>
  <p>Click the button to display the array values after the split.</p>
  <button onclick="myFunction()">Try it</button>
  <p id="demo"></p>
</body>

</html>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接