Рядок запиту 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.