查询字符串在url中取消最后一个')'

问题描述 投票:0回答:2

我正在根据是否选中复选框在Javascript中构建查询字符串。

复选框中的一些选项是

  • “年报”
  • “草”
  • “灌木(常青树)”
  • “灌木(落叶)”

我在网上找到了一个更新url参数的函数:

function updateUrlParameter(uri, key, value) {
  value = value.replace(/\s/g, "%20");
  var i = uri.indexOf('#');
  var hash = i === -1 ? '' : uri.substr(i);
  uri = i === -1 ? uri : uri.substr(0, i);
  var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
  var separator = uri.indexOf('?') !== -1 ? "&" : "?";

  if (!value) {
    // remove key-value pair if value is empty
    uri = uri.replace(new RegExp("([&]?)" + key + "=.*?(&|$)", "i"), '');
    if (uri.slice(-1) === '?') {
        uri = uri.slice(0, -1);
    }
  } else {
    console.log("value is " + value)
    uri = uri + separator + key + "=" + value;
  }
  return uri + hash;
}

使用上面的函数,如果我从上到下检查上面四个的复选框,我的查询字符串就变成了

?plantType=Annual&plantType=Grass&plantType=Shrub%20(Evergreen)&plantType=Shrub%20(Deciduous

为什么函数忽略字符串中的最后一个')'?有没有解决这个问题?我想在查询字符串中保留括号,因为这将使查询数据库更容易。

我创建了一个迭代输入复选框的函数。如果选中它们,则使用updateUrlParameter函数更新URI。

function getQueryString() {
  var inputsContainerChildren = $('#floatingDivForFilter').children();
  var input = document.createElement('input')
  var uri = '';

  for (var i = 0; i < inputsContainerChildren.length; i++) {
    var currChild = inputsContainerChildren[i].firstElementChild;
    if (currChild) {
        if (currChild.tagName === 'INPUT') {
            if (currChild.checked) {
                var id = currChild.id;
                    console.log(uri)
                    uri  = updateUrlParameter(uri, currChild.name, currChild.value);
            }
        }
    }
} 
console.log(uri);

}

下面的照片显示了生成的URL的快照。我无法弄清楚为什么最后'''被切掉了。 url photo

javascript string url
2个回答
0
投票

您看到的问题只是Chrome开发人员工具试图过于聪明。

将网址记录到控制台时,Chrome无法将完整网址识别为链接,但会排除结束“)”。他们可能会这样做,因为人们在大括号中写一个url是很常见的,并且预计闭合括号不是url的一部分。

由于这只是开发人员工具的问题,因此您可以忽略该问题。它不会影响代码的运行时行为。

当您正确地转义参数中的特殊字符时,问题将得到解决(正如您应该做的那样):

function updateUrlParameter(uri, key, value) {
  // removed because escape will do that 
  // value = value.replace(/\s/g, "%20");
  var i = uri.indexOf('#');
  var hash = i === -1 ? '' : uri.substr(i);
  uri = i === -1 ? uri : uri.substr(0, i);
  var separator = uri.indexOf('?') !== -1 ? "&" : "?";

  if (!value) {
    // remove key-value pair if value is empty
    uri = uri.replace(new RegExp("([&]?)" + key + "=.*?(&|$)", "i"), '');
    if (uri.slice(-1) === '?') {
        uri = uri.slice(0, -1);
    }
  } else {
    console.log("value is " + value)
    // Use escape on key and value
    uri = uri + separator + escape(key) + "=" + escape(value);
  }
  return uri + hash;
}

let s = "http://chrome.is.too.clever/";
s = updateUrlParameter(s, "plantType", "Annual");
s = updateUrlParameter(s, "plantType", "Grass");
s = updateUrlParameter(s, "plantType", "Shrub (Evergreen)");
s = updateUrlParameter(s, "plantType", "Shrub (Deciduous)");
console.log(s);

Fiddle


0
投票

不要使用正则表达式,只需将参数转换为对象,修改所述对象,然后将其转换回参数。

var url = 'https://x.y?plantType=Annual&plantType=Grass&plantType=Shrub%20(Evergreen)&plantType=Shrub%20(Deciduous)';

function updateUrlParameter(uri, key, value) {
  let url = new URL(uri), object = deserializeQuery(url.search); // params to obj
  object[key] = value; // modify obj
  return url.origin + '?' + serializeQuery(object); // obj to url + params
}

console.log(updateUrlParameter(url, 'plantType', [ 'Pine', 'Palm', 'Rose (Red)' ]));

/** ======= Serialization / Deserialization functions below ======== */

// https://stackoverflow.com/a/47517503/1762224
function deserializeQuery(queryString, queryKey) {
  let query = {}, pairs = (queryString[0] === '?' ? queryString.substr(1) : queryString).split('&');
  for (var i = 0; i < pairs.length; i++) {
    var pair = pairs[i].split('='), key = decodeURIComponent(pair[0]), value = decodeURIComponent(pair[1] || '');
    value = (value.indexOf(',') === -1 ? value : value.split(','));
    query[key] = query[key] ? (query[key].constructor === Array ? query[key].concat(value) : [query[key], value]) : value;
  }
  return typeof queryKey === 'undefined' ? query : query[queryKey];
}

// https://stackoverflow.com/a/53528203/1762224
function serializeQuery(params, keys = [], isArray = false) {
  const p = Object.keys(params).map(key => {
    let val = params[key];
    if ("[object Object]" === Object.prototype.toString.call(val) || Array.isArray(val)) {
      keys.push(Array.isArray(params) ? "" : key);
      return serializeQuery(val, keys, Array.isArray(val));
    } else {
      let tKey = keys.length > 0 ? ((isArray ? keys : [...keys, key]).reduce((str, k) => "" === str ? k : `${str}[${k}]`, "")) : key;
      if (isArray) {
        return encodeURIComponent(tKey) + '=' + encodeURIComponent(val);
      }
    }
  }).join('&');
  keys.pop();
  return p;
}
.as-console-wrapper {
  top: 0;
  max-height: 100% !important;
}

.as-console-row {
  white-space: pre-wrap;
  word-break: break-all;
}
© www.soinside.com 2019 - 2024. All rights reserved.