Строка запроса берет последний ")" в URL - PullRequest
0 голосов
/ 07 марта 2019

Я строю строку запроса в Javascript, основываясь на том, установлен флажок или нет.

Некоторые опции в флажках:

  • "Годовой"
  • "Grass"
  • "Кустарник (вечнозеленый)"
  • "Кустарник (лиственный)"

Я нашел в сети функцию, которая обновляет параметр 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

Ответы [ 2 ]

0 голосов
/ 07 марта 2019

Вместо использования регулярного выражения просто преобразуйте параметры в объект, измените указанный объект и преобразуйте его обратно в параметры.

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;
}
0 голосов
/ 07 марта 2019

Проблема, с которой вы столкнулись, заключается в том, что инструменты разработчика Chrome пытаются быть слишком умными.

При регистрации URL-адреса на консоли Chrome не распознает полный URL-адрес как ссылку, а исключает закрытие ")».Они, вероятно, делают это, потому что очень часто люди пишут 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...