JavaScript sorgu dizesi [kapalı]


106

Sorgu dizesi ASP.NETstilinden sözlük oluşturan herhangi bir JavaScript kitaplığı var mı ?

Gibi kullanılabilecek bir şey:

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

Is "sorgu dizesi" dışında başka bir şey denir .NETalemine? Neden location.searchbir anahtar / değer koleksiyonuna ayrılmıyor ?

DÜZENLEME : Kendi işlevimi yazdım, ancak herhangi bir büyük JavaScript kitaplığı bunu yapıyor mu?





1
@davidtaubmann biri daha yaşlıysa, tersi olur. Esasen aynı şeyi sormaları komik, ancak sorunun formatı nedeniyle biri şöhreti topluluğa dönüştürdü ve diğeri konu dışı olarak kapatıldı.
Andre Figueiredo

Yanıtlar:


11

37
Bu,
jquery'ye

@EvanMulawski Teşekkürler. Görünüşe göre eklenti kayboldu. Yardımcı olabilecek farklı bir bağlantı ekledim.
Shadow2531

CMS tarafından sağlanan yöntem daha kolay ve daha temizdir. Esp. Zaten jquery kullanmıyorsanız.
jcoffland

1
Bunu yapmak için bu kütüphaneye başvurabilirsiniz - github.com/Mikhus/jsurl
Mikhus

1
İşte doğru bağlantı: plugins.jquery.com/query-object
thexfactor

230

Anahtar / değer çiftlerini location.search özelliğinden çıkarabilirsiniz , bu özellik URL'nin? dahil olmak üzere? sembol.

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
Bu bir galibiyet değil. Bir anahtarın değerinde '=' karakteri varsa ne olur? Örneğin dork.com/?equation=10=2. URL kodlu olması gerektiğini iddia edebilirsiniz, ancak kesinlikle olması gerekmiyor. Bir keresinde ben de böyle saf bir işlev yazma hatasını yaptım. Bu işlevin hesaba kattığı birden fazla uç durum vardır.
JamesBrownIsDead

6
@James, birkaç ay önce işlevi değiştirdiğimi söylemeyi unuttum, şimdi örneğinizi doğru şekilde işleyebilir dork.com/?equation=10=2...
CMS

2
@CMS, bu şekilde temsil edilen bir sorgu dizesindeki bir dizinin olasılığını işlemez, ?val=foo&val=bar&val=baz buna nasıl uyum sağlarsınız ?
Russ Bradberry

2
@RussBradberry Gerçekten sahip olamazsınız val=foo&val=bar&val=baz; olması gerekirdival[]=foo&val[]=bar&val[]=baz
Brian Driscoll

1
Benim değerleri boşluk vardı ve benim vars ile sona erdi zaman bana eksik gibiydi %20s' ı değiştirilir, böylece result[keyValuePair[0]] = keyValuePair[1] || '';ileresult[keyValuePair[0]] = decodeURIComponent((keyValuePair[1]+'').replace(/\+/g, '%20')) || '';
user24601

22

vanilya javascript kullanarak tek (ish) kod satırında tl; dr çözümü

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

Sorgu dizesi ?a=1&b=2&c=3&d&eiçin şunu döndürür:

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

çok değerli anahtarlar ve kodlanmış karakterler ?

JavaScript’te sorgu dizesi değerlerini nasıl alabilirim? Adresindeki orijinal yanıta bakın.

"?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
bu tek bir satır değil - kötü biçimlendirilmiş birkaç satır var!
JonnyRaa

1
Kahretsin, ne diyeceğimi bilmiyorum ... Beni yakaladın. Burada, çok satırlı bir çözüm bulun: `var queryDict = {}; location.search.substr (1) .split ("&"). forEach (function (öğe) {queryDict [item.split ("=") [0]] = item.split ("=") [1]; }); ``
Qwerty

2
haha onu seviyorum! Özür dilerim, eskiden 'x yapan bir satır buldum' diyen ve sonra size sadece satır sonlarıyla 3 satır gösteren biriyle çalışıyordum!
JonnyRaa

@JonnyLeeds Sorun değil, tam olarak ne demek istediğini biliyorum, ama o zaman neden her biri yeni satıra zincirlenmiş komutları yazsın ki? Daha sonra, parametre olarak verilen bir fonksiyon vardır (parametreler genellikle satır içindedir) ve sadece tek bir ataması vardır. Satır içi olmak için çığlık atıyor! : D
Qwerty

1
@Qwerty, bunun nedeni muhtemelen "tek satırınızın" yeniden biçimlendirilmesi gerektiğidir, böylece onu okumak yatay kaydırma gerektirmez. Ben ayarladım.
P i

8

Bu yazıyı bulduktan sonra, kendime bakarken, en çok oy alan çözümün en iyisi olduğunu düşünmediğimi eklemem gerektiğini düşündüm. Dizi değerlerini işlemez (? A = foo & a = bar gibi - bu durumda a'nın ['foo', 'bar'] döndürmesini beklerim). Ayrıca söyleyebileceğim kadarıyla kodlanmış değerleri hesaba katmıyor - örneğin% 20'nin bir boşluğu temsil ettiği onaltılık karakter kodlaması (örnek:? A = Merhaba% 20World) veya bir boşluğu temsil etmek için kullanılan artı sembolü (örnek :? a = Merhaba + Dünya).

Node.js, sorgu dizgisini ayrıştırmaya çok eksiksiz bir çözüm gibi görünen bir şey sunar. Oldukça iyi izole edilmiş ve müsaadeli bir lisans altında olduğu için kendi projenizde çıkarmanız ve kullanmanız kolay olacaktır.

Kodu buradan görüntülenebilir: https://github.com/joyent/node/blob/master/lib/querystring.js

Node'un sahip olduğu testler burada görülebilir: https://github.com/joyent/node/blob/master/test/simple/test-querystring.js Nasıl olduğunu görmek için bunlardan bazılarını popüler yanıtla denemenizi öneririm. onları idare ediyor.

Bu işlevselliği özellikle eklemek için dahil olduğum bir proje de var. Python standart lib sorgu dizisi ayrıştırma modülünün bir bağlantı noktasıdır. Çatalım burada bulunabilir: https://github.com/d0ugal/jquery.qeeree


Kodu Node'dan ödünç almak yok, js, oldukça iç içe geçmiş durumda.
alfwatt

5

Ya da sugar.js kitaplığını kullanabilirsiniz .

Sugarjs.com'dan:

Object.fromQueryString (str , deep = true )

Bir URL'nin sorgu dizesini bir nesneye dönüştürür. Derin yanlışsa, dönüştürme yalnızca yüzeysel parametreleri kabul eder (yani, [] sözdizimine sahip hiçbir nesne veya diziler) evrensel olarak desteklenmez.

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

Misal:

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

3

Elinizde sorgu dizesi varsa, şunu kullanın:

 /**
 * @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);

Bu, yukarıdaki en yüksek oyu alan yanıtta "Güncelleme: normal ifade kullanmaya gerek yok" koduyla aşağı yukarı aynıdır . Bu soruda da benzer kodlar var ). Kaçırdığınız decodeURIComponenten azından çıkartılan dizeleri üzerinde.
Rup

@Rup, bu cevaptan sonra güncelleme yapıldı.
Qwerty

@Qwerty Hayır değildi: güncelleme Şubat 2013 iken bu cevap yaklaşık bir yıl sonra Şubat 2014'teydi. Ama kimin umurunda, uçuşan benzer kodlar var. decodeURIComponentYine de stantla ilgili yorumlarım .
Rup

@Rup Evet, üzgünüm. Ve evet.
Qwerty

2

John Slegers'ın bahsettiği kitaplığın bir jQuery bağımlılığı olduğunu belirtmek gerekir, ancak burada vanilya Javascript olan bir sürüm var.

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

Gönderisine basitçe yorum yapardım, ancak bunu yapacak itibarım yok. : /

Misal:

Aşağıdaki örnek, düzensiz de olsa aşağıdaki sorgu dizesini işler:

?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>



2

Kod

Eldon McGuinness'in bu Özü, şimdiye kadar gördüğüm bir JavaScript sorgu dizisi ayrıştırıcısının açık ara en eksiksiz uygulamasıdır.

Ne yazık ki, bir jQuery eklentisi olarak yazılmıştır.

Vanilla JS'ye yeniden yazdım ve birkaç iyileştirme yaptım:

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;
}

Bu nasıl kullanılır

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");

Çıktı

{
  "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"
  ]
}

Ayrıca bu Fiddle'a bakın .


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]);
        }
    }
}

Ayrıca hfname eşleşmesinin büyük / küçük harfe duyarlı olmasını istiyorsanız adı .toLowerCase () de kullanabilirsiniz.
Shadow2531

Değerin boş olup olmadığını da kontrol edebilirsiniz. Öyleyse, dizinin yalnızca boş olmayan değerler içermesi için girişi eklemeyi atlayabilirsiniz.
Shadow2531

1
unescape (), UTF-8 dizilerini işlemez, bu nedenle decodeURIComponent () kullanmak isteyebilirsiniz. Bununla birlikte, + karakterlerin kodunun boşluklara dönüştürülmesini istiyorsanız, kod çözmeden önce dizede .replace (/ \ + / g, "") komutunu çalıştırın.
Shadow2531

1

Basit, okunaklı ve küçük kalmasını seviyorum.

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);

Misal:

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

1

Saf javascript dize manipülasyonuyla buna benzer bir gereksinim için yazdığım işlev

"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;
}

Kullanım:

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

Düzgün, ama başrolü kaldırmanın dışında, ?temelde üstünüzdeki iki cevapla aynı mı?
Rup

Sadece küçük bir gelişme. Yöntemin kullanılma şekli, bunu kullanıcı için kolaylaştırır. Kullanıcının yalnızca hangi sorgu dizesi değerine ihtiyacı olduğunu bilmesi gerekir.
Pranavan Maru

1

Lodash + ES6 kullanıyorsanız, işte tek satırlık bir çözüm: _.object(window.location.search.replace(/(^\?)/, '').split('&').map(keyVal => keyVal.split('=')));


0

Tamam, herkes asıl sorumu görmezden geldiğine göre, heh, benimkini de göndereceğim! İşte sahip olduğum şey:

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;
})();

Ve testler:

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

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

Unutmayın, JavaScript benim ana dilim değil.

Her neyse, zaten yazılmış bir JavaScript kitaplığı (örn. JQuery, Prototype) arıyorum. :)


1
Yukarıdaki üç satırlık kod miktarını yapmak için gerçekten bir kitaplığa ihtiyacınız olduğuna ikna olmadım! Yine de, en azından bir kitaplığın hem anahtarı hem de değeri decodeURIComponent () 'i hatırlamasını umarsınız, şimdiye kadar yayınlanan her kod parçacığı bunu başaramadı.
bobince

Bir kitaplığa ihtiyacınız yok. Uygulamamı bir kütüphanedeki bir uygulamayla karşılaştırmak istedim, böylece uç durumlardan herhangi birinin eksik olup olmadığını görebildim. :)
çekirdek

javascript ana diliniz değil, bu ne anlama geliyor, kullanmak için bir kütüphaneye ihtiyacınız olsa bile onu öğrenmelisiniz
Marwan

0

@CMS'nin cevabına dayanarak aşağıdakilere sahibim (kolayca JavaScript'e dönüştürülebilen CoffeeScript'te):

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

İhtiyacınız olanı kolayca elde edebilirsiniz:

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

Buradaki kazanç, nesne yönelimli bir arayüzdür (işlevsel olmak yerine) ve herhangi bir dizede yapılabilir (sadece konum arama değil).

Zaten bir JavaScript kitaplığı kullanıyorsanız, bu işlev zaten var olur. Örneğin , Prototip'in sürümü burada

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.