Строка запроса JavaScript [закрыто]


106

Есть ли какая-нибудь библиотека JavaScript, которая делает словарь из строки запроса, ASP.NET стиля?

Что-то, что можно использовать как:

var query = window.location.querystring["query"]?

Является ли «Строка запроса» называется что - то еще за пределами .NETобласти? Почему не location.searchразбивается на коллекцию ключей / значений ?

РЕДАКТИРОВАТЬ : Я написал свою собственную функцию, но делает ли это какая-либо основная библиотека JavaScript?


3
нашел это: medialize.github.com/URI.js
deerchao



1
@davidtaubmann, что один старше, было бы наоборот. Забавно, что они, по сути, задают одно и то же, но из-за формата вопроса одни прославляют сообщество, а другие закрывают как не по теме.
Андре Фигейредо

Ответы:


11

37
Это должно быть родным для jquery
gcb

@EvanMulawski Спасибо. Плагин вроде просто пропал. Я добавил другую ссылку, которая может помочь.
Shadow2531

Метод, предоставляемый CMS, проще и понятнее. Esp. если вы еще не используете jquery.
jcoffland 05

1
Для этого вы можете обратиться к этой библиотеке - github.com/Mikhus/jsurl
Mikhus

1
Вот правильная ссылка: plugins.jquery.com/query-object
thexfactor

230

Вы можете извлечь пары ключ / значение из свойства location.search , это свойство имеет часть URL-адреса, следующую за? символ, включая? условное обозначение.

function getQueryString() {
  var result = {}, queryString = location.search.slice(1),
      re = /([^&=]+)=([^&]*)/g, m;

  while (m = re.exec(queryString)) {
    result[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
  }

  return result;
}

// ...
var myParam = getQueryString()["myParam"];

11
Это не победа. Что делать, если в значении ключа есть символ '='? Например, dork.com/?equation=10=2. Вы можете возразить, что он ДОЛЖЕН быть закодирован в URL-адресе, но это не обязательно. Я однажды сделал ошибку, написав такую ​​наивную функцию. Эта функция учитывает более одного граничного случая.
JamesBrownIsDead

6
@James, забыл упомянуть, что пару месяцев назад я изменил функцию, теперь она корректно справляется с вашим примером dork.com/?equation=10=2...
CMS

2
@CMS это не обрабатывает возможность массива в строке запроса, которая представлена ​​как таковая, ?val=foo&val=bar&val=baz как бы вы это разместили?
Расс Брэдберри

2
@RussBradberry Вы действительно не можете иметь val=foo&val=bar&val=baz; так должно бытьval[]=foo&val[]=bar&val[]=baz
Брайан Дрисколл

1
Мне это казалось неполным, когда в моих значениях были пробелы, а мои vars заканчивались на %20's, поэтому я заменил его result[keyValuePair[0]] = keyValuePair[1] || '';наresult[keyValuePair[0]] = decodeURIComponent((keyValuePair[1]+'').replace(/\+/g, '%20')) || '';
user24601 09

22

tl; dr решение в одной (ish) строке кода с использованием ванильного javascript

var queryDict = {}
location.search.substr(1).split("&").forEach(function(item) {
    queryDict[item.split("=")[0]] = item.split("=")[1]
})

Для строки запроса ?a=1&b=2&c=3&d&eвозвращается:

> queryDict
a: "1"
b: "2"
c: "3"
d: undefined
e: undefined

многозначные ключи и закодированные символы ?

См. Исходный ответ в разделе Как получить значения строки запроса в JavaScript?

"?a=1&b=2&c=3&d&e&a=5&a=t%20e%20x%20t&e=http%3A%2F%2Fw3schools.com%2Fmy%20test.asp%3Fname%3Dståle%26car%3Dsaab"
> queryDict
a: ["1", "5", "t e x t"]
b: ["2"]
c: ["3"]
d: [undefined]
e: [undefined, "http://w3schools.com/my test.asp?name=ståle&car=saab"]

8
это не одна строка - это несколько плохо отформатированных строк!
JonnyRaa

1
Блин, не знаю, что сказать ... Ты меня поймал. Вот несколько вариантов решения: `var queryDict = {}; location.search.substr (1) .split ("&"). forEach (функция (элемент) {queryDict [item.split ("=") [0]] = item.split ("=") [1]; }); `
Qwerty

2
хаха, мне это нравится! Извините, я работал с кем-то, кто говорил: «Я нашел один лайнер, который делает x», а затем просто показывал вам 3 строки с удаленными разрывами строк!
JonnyRaa

@JonnyLeeds Нет проблем, я точно знаю, что вы имеете в виду, но тогда зачем писать каждую из связанных команд на новой строке? Затем есть функция, заданная как параметр (параметры обычно встроены), которая имеет только одно назначение. Он кричит, чтобы его вставили! : D
Qwerty

1
@Qwerty, это, вероятно, потому, что ваш "однострочный" файл должен быть переформатирован, чтобы его чтение не требовало горизонтальной прокрутки. Я это отрегулировал.
P i

8

После того, как я нашел этот пост, я подумал, что должен добавить, что не думаю, что решение, получившее наибольшее количество голосов, является лучшим. Он не обрабатывает значения массива (например,? A = foo & a = bar - в этом случае я ожидал бы, что a вернет ['foo', 'bar']). Он также, насколько я могу судить, не принимает во внимание закодированные значения, такие как шестнадцатеричная кодировка символов, где% 20 представляет пробел (пример:? A = Hello% 20World) или символ плюса, используемый для представления пробела (пример :? a = Привет + Мир).

Node.js предлагает то, что выглядит как очень полные решения для синтаксического анализа строки запроса. Его было бы легко извлечь и использовать в своем собственном проекте, поскольку он достаточно хорошо изолирован и находится под разрешающей лицензией.

Код для него можно посмотреть здесь: https://github.com/joyent/node/blob/master/lib/querystring.js

Тесты, которые есть в Node, можно увидеть здесь: https://github.com/joyent/node/blob/master/test/simple/test-querystring.js Я бы предложил попробовать некоторые из них с популярным ответом, чтобы увидеть, как это обрабатывает их.

Еще есть проект, в котором я участвовал, чтобы специально добавить эту функцию. Это порт стандартного модуля синтаксического анализа строки запроса библиотеки Python. Мой форк можно найти здесь: https://github.com/d0ugal/jquery.qeeree


Нельзя просто заимствовать код из Node, js, он очень взаимосвязан.
alfwatt

5

Или вы можете использовать библиотеку sugar.js .

С сайта sugarjs.com:

Object.fromQueryString (str , deep = true )

Преобразует строку запроса URL-адреса в объект. Если deep имеет значение false, преобразование будет принимать только поверхностные параметры (т.е. без объектов или массивов с синтаксисом []), поскольку они не поддерживаются повсеместно.

Object.fromQueryString('foo=bar&broken=wear') >{"foo":"bar","broken":"wear"}
Object.fromQueryString('foo[]=1&foo[]=2') >{"foo":[1,2]}

Пример:

var queryString = Object.fromQueryString(location.search);
var foo = queryString.foo;

3

Если у вас есть строка запроса, используйте это:

 /**
 * @param qry the querystring
 * @param name name of parameter
 * @returns the parameter specified by name
 * @author eduardo.medeirospereira@gmail.com
 */

function getQueryStringParameter(qry,name){
    if(typeof qry !== undefined && qry !== ""){
        var keyValueArray = qry.split("&");
        for ( var i = 0; i < keyValueArray.length; i++) {
            if(keyValueArray[i].indexOf(name)>-1){
                return keyValueArray[i].split("=")[1];
            }
        }
    }
    return "";
}

2
// How about this
function queryString(qs) {
    var queryStr = qs.substr(1).split("&"),obj={};
    for(var i=0; i < queryStr.length;i++)
        obj[queryStr[i].split("=")[0]] = queryStr[i].split("=")[1];
    return obj;
}

// Usage:
var result = queryString(location.search);

Это более или менее похоже на код «Обновление: не нужно использовать регулярное выражение» в ответе с наибольшим количеством голосов выше. В этом вопросе также есть множество аналогичного кода ). По decodeURIComponentкрайней мере, вам не хватает извлеченных строк.
Rup

@Rup, обновление было сделано после этого ответа.
Qwerty

@Qwerty Нет, не было: обновление было в феврале 2013 года, тогда как этот ответ был почти годом позже, в феврале 2014 года. Но кого это волнует, есть много похожего кода. Впрочем, мои комментарии по поводу decodeURIComponentстенда.
Rup

@Rup Ага, извини. Ага.
Qwerty

2

Стоит отметить, что упомянутая Джоном Слегерсом библиотека действительно имеет зависимость от jQuery, но вот версия, которая является ванильным Javascript.

https://github.com/EldonMcGuinness/querystring.js

Я бы просто прокомментировал его пост, но у меня нет репутации для этого. : /

Пример:

В приведенном ниже примере обрабатывается следующая, хотя и нерегулярная, строка запроса:

?foo=bar&foo=boo&roo=bar;bee=bop;=ghost;=ghost2;&;checkbox%5B%5D=b1;checkbox%5B%5D=b2;dd=;http=http%3A%2F%2Fw3schools.com%2Fmy%20test.asp%3Fname%3Dst%C3%A5le%26car%3Dsaab&http=http%3A%2F%2Fw3schools2.com%2Fmy%20test.asp%3Fname%3Dst%C3%A5le%26car%3Dsaab 

var qs = "?foo=bar&foo=boo&roo=bar;bee=bop;=ghost;=ghost2;&;checkbox%5B%5D=b1;checkbox%5B%5D=b2;dd=;http=http%3A%2F%2Fw3schools.com%2Fmy%20test.asp%3Fname%3Dst%C3%A5le%26car%3Dsaab&http=http%3A%2F%2Fw3schools2.com%2Fmy%20test.asp%3Fname%3Dst%C3%A5le%26car%3Dsaab";
//var qs = "?=&=";
//var qs = ""

var results = querystring(qs);

(document.getElementById("results")).innerHTML =JSON.stringify(results, null, 2);
<script 
src="https://rawgit.com/EldonMcGuinness/querystring.js/master/dist/querystring.min.js"></script>
<pre id="results">RESULTS: Waiting...</pre>


На самом деле, я удалил зависимость jQuery в коде, который дал в своем ответе ;-)
Джон Слегерс

2

Код

Этот Gist Элдона МакГиннесса , безусловно, является наиболее полной реализацией синтаксического анализатора строки запроса JavaScript, которую я когда-либо видел.

К сожалению, он написан как плагин jQuery.

Я переписал его на ванильный JS и сделал несколько улучшений:

function parseQuery(str) {
  var qso = {};
  var qs = (str || document.location.search);
  // Check for an empty querystring
  if (qs == "") {
    return qso;
  }
  // Normalize the querystring
  qs = qs.replace(/(^\?)/, '').replace(/;/g, '&');
  while (qs.indexOf("&&") != -1) {
    qs = qs.replace(/&&/g, '&');
  }
  qs = qs.replace(/([\&]+$)/, '');
  // Break the querystring into parts
  qs = qs.split("&");
  // Build the querystring object
  for (var i = 0; i < qs.length; i++) {
    var qi = qs[i].split("=");
    qi = qi.map(function(n) {
      return decodeURIComponent(n)
    });
    if (typeof qi[1] === "undefined") {
      qi[1] = null;
    }
    if (typeof qso[qi[0]] !== "undefined") {

      // If a key already exists then make this an object
      if (typeof (qso[qi[0]]) == "string") {
        var temp = qso[qi[0]];
        if (qi[1] == "") {
          qi[1] = null;
        }
        qso[qi[0]] = [];
        qso[qi[0]].push(temp);
        qso[qi[0]].push(qi[1]);

      } else if (typeof (qso[qi[0]]) == "object") {
        if (qi[1] == "") {
          qi[1] = null;
        }
        qso[qi[0]].push(qi[1]);
      }
    } else {
      // If no key exists just set it as a string
      if (qi[1] == "") {
        qi[1] = null;
      }
      qso[qi[0]] = qi[1];
    }
  }
  return qso;
}

Как это использовать

var results = parseQuery("?foo=bar&foo=boo&roo=bar;bee=bop;=ghost;=ghost2;&;checkbox%5B%5D=b1;checkbox%5B%5D=b2;dd=;http=http%3A%2F%2Fw3schools.com%2Fmy%20test.asp%3Fname%3Dst%C3%A5le%26car%3Dsaab&http=http%3A%2F%2Fw3schools2.com%2Fmy%20test.asp%3Fname%3Dst%C3%A5le%26car%3Dsaab");

Вывод

{
  "foo": ["bar", "boo" ],
  "roo": "bar",
  "bee": "bop",
  "": ["ghost", "ghost2"],
  "checkbox[]": ["b1", "b2"],
  "dd": null,
  "http": [
    "http://w3schools.com/my test.asp?name=ståle&car=saab",
    "http://w3schools2.com/my test.asp?name=ståle&car=saab"
  ]
}

См. Также этот Fiddle .


1

function decode(s) {
    try {
        return decodeURIComponent(s).replace(/\r\n|\r|\n/g, "\r\n");
    } catch (e) {
        return "";
    }
}
function getQueryString(win) {
    var qs = win.location.search;
    var multimap = {};
    if (qs.length > 1) {
        qs = qs.substr(1);
        qs.replace(/([^=&]+)=([^&]*)/g, function(match, hfname, hfvalue) {
            var name = decode(hfname);
            var value = decode(hfvalue);
            if (name.length > 0) {
                if (!multimap.hasOwnProperty(name)) {
                    multimap[name] = [];
                }
                multimap[name].push(value);
            }
        });
    }
    return multimap;
}
var keys = getQueryString(window);
for (var i in keys) {
    if (keys.hasOwnProperty(i)) {
        for (var z = 0; z < keys[i].length; ++z) {
            alert(i + ":" + keys[i][z]);
        }
    }
}

Вы также можете использовать .toLowerCase () имя, если хотите, чтобы сопоставление hfname производилось без учета регистра.
Shadow2531,

Вы также можете проверить, является ли значение пустым или нет. Если это так, вы можете пропустить добавление записи, чтобы массив содержал только непустые значения.
Shadow2531,

1
unescape () не обрабатывает последовательности UTF-8, поэтому вы можете использовать decodeURIComponent (). Однако, если вы хотите, чтобы символы + были декодированы в пробелы, запустите .replace (/ \ + / g, "") в строке перед декодированием.
Shadow2531

1

Мне нравится, чтобы он был простым, читаемым и маленьким.

function searchToObject(search) {
    var pairs = search.substring(1).split("&"),
        obj = {}, pair;

    for (var i in pairs) {
        if (pairs[i] === "") continue;
        pair = pairs[i].split("=");
        obj[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
    }
    return obj;
}

searchToObject(location.search);

Пример:

searchToObject('?query=myvalue')['query']; // spits out: 'myvalue'

1

Функция, которую я написал для требования, аналогичного этому, с чистым манипулированием строкой javascript

"http://www.google.lk/?Name=John&Age=20&Gender=Male"

function queryize(sampleurl){
    var tokens = url.split('?')[1].split('&');
    var result = {};

    for(var i=0; i<tokens.length; i++){
        result[tokens[i].split('=')[0]] = tokens[i].split('=')[1];
    }

    return result;
}

Использование:

queryize(window.location.href)['Name'] //returns John
queryize(window.location.href)['Age'] //returns 20
queryize(window.location.href)['Gender'] //returns Male

Красиво, но помимо того, как вы удаляете ведущую часть, ?это в основном то же самое, что и два ответа выше вас?
Rup

Просто небольшое улучшение. Способ использования метода упрощает для пользователя. Пользователю нужно только знать, какое значение строки запроса ему нужно.
Пранаван Мару

1

Если вы используете lodash + ES6, вот однострочное решение: _.object(window.location.search.replace(/(^\?)/, '').split('&').map(keyVal => keyVal.split('=')));


0

Хорошо, раз все игнорируют мой вопрос, хех, я тоже отправлю свой! Вот что у меня есть:

location.querystring = (function() {

    // The return is a collection of key/value pairs

    var queryStringDictionary = {};

    // Gets the query string, starts with '?'

    var querystring = unescape(location.search);

    // document.location.search is empty if no query string

    if (!querystring) {
        return {};
    }

    // Remove the '?' via substring(1)

    querystring = querystring.substring(1);

    // '&' seperates key/value pairs

    var pairs = querystring.split("&");

    // Load the key/values of the return collection

    for (var i = 0; i < pairs.length; i++) {
        var keyValuePair = pairs[i].split("=");
        queryStringDictionary[keyValuePair[0]] = keyValuePair[1];
    }

    // Return the key/value pairs concatenated

    queryStringDictionary.toString = function() {

        if (queryStringDictionary.length == 0) {
            return "";
        }

        var toString = "?";

        for (var key in queryStringDictionary) {
            toString += key + "=" + queryStringDictionary[key];
        }

        return toString;
    };

    // Return the key/value dictionary

    return queryStringDictionary;
})();

И тесты:

alert(window.location.querystring.toString());

for (var key in location.querystring) {
    alert(key + "=" + location.querystring[key]);
}

Вы подумали, что JavaScript не мой родной язык.

В любом случае, я ищу библиотеку JavaScript (например, jQuery, Prototype), в которой она уже написана. :)


1
Я не уверен, что вам действительно нужна библиотека, чтобы делать то, что составляет три строки кода выше! Тем не менее, по крайней мере, вы можете надеяться, что библиотека запомнит decodeURIComponent () как ключ, так и значение, чего не удалось сделать в каждом опубликованном фрагменте кода.
bobince

Вам не нужна библиотека. Я хотел сравнить свою реализацию с реализацией в библиотеке, чтобы увидеть, не пропущены ли какие-либо крайние случаи. :)
core

javascript - не ваш родной язык, что это значит, вы должны выучить его, даже если вам нужна библиотека для использования
Марван

0

Основываясь на ответе @CMS, у меня есть следующее (в CoffeeScript, который можно легко преобразовать в JavaScript):

String::to_query = ->
  [result, re, d] = [{}, /([^&=]+)=([^&]*)/g, decodeURIComponent]
  while match = re.exec(if @.match /^\?/ then @.substring(1) else @)
    result[d(match[1])] = d match[2] 
  result

Вы можете легко взять то, что вам нужно:

location.search.to_query()['my_param']

Победа здесь - объектно-ориентированный интерфейс (вместо функционального), и это можно сделать с любой строкой (а не только с location.search).

Если вы уже используете библиотеку JavaScript, эта функция уже существует. Например, вот версия Prototype

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.