Рядок запиту JavaScript [закрито]


106

Чи є бібліотека JavaScript, яка створює словник із рядка запиту, ASP.NETстилю?

Щось, що може бути використано на зразок:

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

Чи називається "рядок запиту" чимось іншим поза .NETсферою? Чому не location.searchрозбивається на колекцію ключів / цінностей ?

EDIT : Я написав власну функцію, але чи робить це якась основна бібліотека JavaScript?


3
знайшов це: medialize.github.com/URI.js
deerchao



1
@davidtaubmann, що хтось старший, це було б обернено. Смішно, що вони по суті задають те саме, але завдяки формату питання один отримав славу, перетворився на спільноту, а інші закрили як поза темою.
Андре Фігейредо

Відповіді:


11

37
Це має бути рідним для jquery
gcb

@EvanMulawski Дякую Плагін просто зник, здається. Я додав інше посилання, яке може допомогти.
Shadow2531

Метод, який надає CMS, простіший і чистіший. Esp якщо ви вже не використовуєте jquery.
jcoffland

1
Ви можете посилатися на цю бібліотеку, щоб це зробити - github.com/Mikhus/jsurl
Міхус,

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
Мені це здалося неповним, коли в моїх значеннях були пробіли, а моє значення закінчилося %20's, тому я замінив result[keyValuePair[0]] = keyValuePair[1] || '';наresult[keyValuePair[0]] = decodeURIComponent((keyValuePair[1]+'').replace(/\+/g, '%20')) || '';
user24601

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
ха-ха, я люблю це! Вибачте, що я працював з тим, хто говорив "Я знайшов один вкладиш, який робить х", а потім просто показую вам 3 рядки з виведеними перервами рядків!
JonnyRaa

@JonnyLeeds Немає проблем, я точно знаю, що ви маєте на увазі, але тоді, чому б ви писали кожну ланцюгову команду в новий рядок? Потім є функція, задана як параметр (параметри зазвичай вбудовані), який має лише одне призначення. Це кричить, щоб накреслити! : D
Qwerty

1
@Qwerty, це, мабуть, тому, що ваш "однолінійний" слід переформатувати, щоб його читання не вимагало горизонтальної прокрутки. Я це відкоригував.
П я

8

Знайшовши цю посаду, дивлячись на себе, я подумав, що мені слід додати, що я не вважаю найкращим рішення з найкращими голосами. Він не обробляє значення масиву (наприклад,? A = foo & a = bar - у цьому випадку я очікую отримання повернення ['foo', 'bar']). Він також, наскільки я можу сказати, не враховує закодовані значення - наприклад, шістнадцяткове кодування символів, де% 20 являє пробіл (приклад:? A = Привіт% 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, я б запропонував спробувати деякі з них із популярною відповіддю, щоб побачити, як це обробляє їх.

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


Існує не просто запозичення коду у Node, js, він сильно переплетений.
alfwatt

5

Або ви можете використати бібліотеку sugar.js .

Від sugarjs.com:

Object.fromQueryString (str , deep = true )

Перетворює рядок запиту URL-адреси в об'єкт. Якщо глибина є хибною, конверсія приймає лише неглибокі параметри (тобто немає об'єкта чи масивів із синтаксисом []), оскільки вони не підтримуються повсюдно.

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 Yup, вибач. І юп.
Qwerty

2

Варто зазначити, що бібліотека, яку згадував Джон Slegers, має залежність від 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 у коді, який я дав у своїй відповіді ;-)
Джон Slegers

2

Код

Цей історія Елдона МакГінесса на сьогодні є найбільш повною реалізацією синтаксичного аналізатора рядків запитів, який я бачив досі.

На жаль, він написаний як плагін 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"
  ]
}

Дивіться також цю скрипку .


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

Вам не потрібна бібліотека. Я хотів порівняти свою реалізацію з такою в бібліотеці, щоб я міг побачити, чи не пропускаю я жодної крайової справи. :)
ядро

javas isnt ваша рідна мова, що це означає, ви повинні вивчити його, навіть якщо вам потрібна бібліотека
Marwan

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, ця функція вже існує. Наприклад, ось версія прототипу

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.