Это строки запроса ошибка-бесплатный парсер?


Я пытался реализовать окончательное, надежное строки запроса URL-адреса парсер, который обрабатывает каждый случай:

  • он пытается быть эффективным, не допуская регулярные выражения
  • он берет полный URL-адресов или просто строки запроса (пока строка запроса начинается с вопросительным знаком)
  • он игнорирует хэш-значение
  • он обрабатывает несколько одинаковых имен параметров
  • он обрабатывает имена параметров, которые равны встроенные методы JavaScript и ключевые слова

Что вы думаете - я что-то пропустил?

function parseURLParams(url) {
  if (url === null) return;

  var queryStart = url.indexOf("?") + 1,
      queryEnd   = url.indexOf("#") + 1 || url.length + 1,
      query      = url.slice(queryStart, queryEnd - 1);

  if (query === url || query === "") return;

  var params = {}, 
      nvPairs = query.replace(/\+/g, " ").split("&");

  for (var i=0; i<nvPairs.length; i++) {
    var nv = nvPairs[i],
        eq = nv.indexOf("=") + 1 || nv.length + 1,
        n  = decodeURIComponent( nv.slice(0, eq - 1) ),
        v  = decodeURIComponent( nv.slice(eq) );
    if ( n !== "" ) {
      if ( !Object.prototype.hasOwnProperty.call(params, n) ) {
        params[n] = [];
      }
      params[n].push(v);
    }
  }
  return params;
}

Он возвращает объект из массива для неразбирающихся URL с запросом строк и неопределенной , если строка запроса не может быть идентифицирована.

Я использовал это в качестве ответа на так.



463
5
задан 13 июня 2011 в 09:06 Источник Поделиться
Комментарии
3 ответа

Это ошибка бесплатно? Нет.

Эти два угла-случаи были пропущены:


  1. значения параметров, содержащие '=', т. е. 'пример.ком?ФОО==бар (двойной знак равенства) или '?фу=к=в'

  2. не может обработать параметров называется 'метод toString' и 'значение' (среди других.)

Первый вполне может рассчитывать как неправильный URL-адрес, но хром ручки и перенести == некодированные в расположение.поиск. Чтобы справиться с этим, вернемся к основной метод indexOf использования.

Вторая проблема просто очень педантичный. Вы могли бы попробовать и обойти его, используя !параметры.метод hasOwnProperty(н) вместо !(N в параметрах), но вы все еще застряли, если кто-то передает параметр называется метод hasOwnProperty. Единственный способ я вижу вокруг это, чтобы возвратиться к некоторым тяжелым основе массива коллекция заполняется что-то вроде:

var keys = [], params = [];
for (...) {
var n = ..., v = ...;
var i = keys.indexOf(n);
if (i >= 0) {
if (!(params[i] instanceof Array)) {
params[i] = [params[i]];
}
params.push(v);
} else {
params[i] = v;
keys.push(n);
}
}

Я думаю, тогда тебе придется прибегнуть к возвращает массив массивов, а не объект. т. е. каждый элемент массива, возвращенного бы быть [ключ, значение] или [ключ [значения]], хотя клиент мог бы найти его легче работать с, если вы вернулись что-то вроде [ключ, значение1, значение2, ...] (который обслуживает хорошо для свойства без значений.)

2
ответ дан 13 июня 2011 в 06:06 Источник Поделиться

вы могли бы сделать проверку на null в параметр url-адреса, так как следующий будет бросать исключение.

parseURLParams(null);

2
ответ дан 14 июня 2011 в 10:06 Источник Поделиться

Кажется, немного более проработанным. Что-то вроде этого должно работать так же хорошо, и адреса пунктов searlea в ответ:

function parseURLParams(url) {
var out = {};
(url.split('?')[1] || url).split('#')[0].split('&').forEach(function(p) {
var kv = p.match(/([^=]*)=?(.*)/),
k = decodeURIComponent(kv[1]),
v = decodeURIComponent(kv[2] || '');
hasOwnProperty.call(out, k) ? out[k].push(v) : out[k] = [v];
});
return out;
}

Регулярное выражение матч нужен только если вы хотите поддержать знаки равенства в ценности, в противном случае вы можете использовать сплит и индексами 0 и 1.

Главная (единственная?) разница в том, что практически любая строка будет рассматриваться как жизнеспособная запрос-если нет никаких знаков равенства или амперсанды, это запрос всего один ключ, и никакое значение.

1
ответ дан 25 апреля 2013 в 02:04 Источник Поделиться