สตริงการสืบค้น JavaScript [ปิด]


106

มีไลบรารี JavaScript ใดที่ทำให้พจนานุกรมออกจากสตริงการสืบค้นASP.NETสไตล์หรือไม่

สิ่งที่สามารถใช้ได้เช่น:

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

เป็น"สตริงแบบสอบถาม"เรียกว่าอย่างอื่นนอก.NETดินแดน? ทำไมไม่location.searchเสียเป็นคอลเลกชันคีย์ / ค่า ?

แก้ไข : ฉันเขียนฟังก์ชันของตัวเอง แต่ไลบรารี JavaScript หลัก ๆ ทำสิ่งนี้หรือไม่


3
พบสิ่งนี้: medialize.github.com/URI.js
deerchao



1
@davidtaubmann อันนั้นเก่ากว่ามันจะผกผัน ตลกดีที่พวกเขาถามแบบเดียวกันเป็นหลัก แต่เนื่องจากรูปแบบของคำถามหนึ่งจึงทำให้ชื่อเสียงกลายเป็นของชุมชนและอื่น ๆ ปิดเป็นหัวข้อ
Andre Figueiredo

คำตอบ:


11

อาจจะhttp://plugins.jquery.com/query-object/ ?

นี่คือส้อมของมันhttps://github.com/sousk/jquery.parsequery#readme


37
สิ่งนี้ควรเป็นของ jquery
gcb

@EvanMulawski ขอบคุณ ดูเหมือนว่าปลั๊กอินจะหายไป ฉันเพิ่มลิงค์อื่นซึ่งอาจช่วยได้
Shadow2531

วิธีการที่จัดทำโดย CMS นั้นง่ายและสะอาดกว่า Esp. หากคุณยังไม่ได้ใช้ jquery
jcoffland

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
@ เจมส์ลืมบอกไปว่าสองสามเดือนก่อนฉันได้แก้ไขฟังก์ชันแล้วตอนนี้มันสามารถจัดการกับตัวอย่างของคุณได้อย่างถูกต้องdork.com/?equation=10=2...
CMS

2
@CMS สิ่งนี้ไม่ได้จัดการกับความเป็นไปได้ของอาร์เรย์ในสตริงการสืบค้นที่แสดง?val=foo&val=bar&val=baz ว่าคุณจะรองรับสิ่งนี้ได้อย่างไร?
Russ Bradberry

2
@RussBradberry คุณไม่มีจริงๆval=foo&val=bar&val=baz; มันจะต้องเป็นval[]=foo&val[]=bar&val[]=baz
Brian Driscoll

1
ดูเหมือนจะไม่สมบูรณ์สำหรับฉันเมื่อค่าของฉันมีช่องว่างและตัวแทนของฉันลงเอยด้วย%20's ดังนั้นฉันจึงแทนที่result[keyValuePair[0]] = keyValuePair[1] || '';ด้วยresult[keyValuePair[0]] = decodeURIComponent((keyValuePair[1]+'').replace(/\+/g, '%20')) || '';
user24601

22

tl; drบนโค้ดบรรทัดเดียว (ish) โดยใช้ vanilla javascript

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

สำหรับ querystring ?a=1&b=2&c=3&d&eจะส่งกลับ:

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

คีย์หลายค่าและอักขระที่เข้ารหัส ?

ดูคำตอบเดิมได้ที่How can get query string values ​​in 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 (function (item) {queryDict [item.split ("=") [0]] = item.split ("=") [1]; }); `
Qwerty

2
ฮ่าฮ่าฉันรักมัน! ขอโทษทีฉันเคยทำงานกับคนที่เคยพูดว่า 'ฉันเจอซับหนึ่งตัวที่ทำ x' แล้วก็แสดง 3 บรรทัดโดยขีดเส้นแบ่งออก!
JonnyRaa

@JonnyLeeds ไม่มีปัญหาฉันรู้ว่าคุณหมายถึงอะไร แต่ทำไมจึงต้องเขียนแต่ละคำสั่งที่ถูกล่ามไว้ในบรรทัดใหม่ จากนั้นมีฟังก์ชั่นที่กำหนดให้เป็นพารามิเตอร์ (พารามิเตอร์มักจะเป็นแบบอินไลน์) ซึ่งมีการกำหนดเพียงครั้งเดียว กรี๊ดดดดดดดดด! : D
Qwerty

1
@Qwerty อาจเป็นเพราะ "ซับเดียว" ของคุณควรได้รับการจัดรูปแบบใหม่เพื่อให้การอ่านไม่ต้องเลื่อนในแนวนอน ฉันปรับมันแล้ว
P

8

หลังจากพบโพสต์นี้เมื่อมองหาตัวเองฉันคิดว่าฉันควรเพิ่มว่าฉันไม่คิดว่าโซลูชันที่ได้รับการโหวตมากที่สุดจะดีที่สุด มันไม่จัดการค่าอาร์เรย์ (เช่น? a = foo & a = bar - ในกรณีนี้ฉันคาดว่าจะได้รับผลตอบแทน ['foo', 'bar']) เท่าที่ฉันสามารถบอกได้ว่าไม่ได้คำนึงถึงค่าที่เข้ารหัสเช่นการเข้ารหัสอักขระเลขฐานสิบหกโดยที่% 20 แสดงถึงช่องว่าง (ตัวอย่าง:? a = Hello% 20World) หรือสัญลักษณ์บวกที่ใช้แทนช่องว่าง (ตัวอย่างเช่น :? a = Hello + World)

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ลึก = จริง)

แปลงสตริงการสืบค้นของ 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);

มากหรือน้อยก็เหมือนกับโค้ด "อัปเดต: ไม่จำเป็นต้องใช้ regex" ในคำตอบที่ได้รับการโหวตสูงสุดด้านบน นอกจากนี้ยังมีรหัสที่คล้ายกันมากมายในคำถามนี้ ) คุณขาดdecodeURIComponentสตริงที่แยกออกมาเป็นอย่างน้อย
รูป

@Rup การอัปเดตเกิดขึ้นหลังจากคำตอบนี้
Qwerty

@Qwerty ไม่มันไม่ใช่: การอัปเดตเมื่อกุมภาพันธ์ 2013 ในขณะที่คำตอบนี้เกือบหนึ่งปีต่อมาในเดือนกุมภาพันธ์ 2014 แต่ใครจะสนใจมีรหัสที่คล้ายกันมากมายที่บินอยู่ ความคิดเห็นของฉันเกี่ยวกับdecodeURIComponentขาตั้งแม้ว่า
Rup

@Rup Yup ขอโทษค่ะ และใช่
Qwerty

2

เป็นที่น่าสังเกตว่าไลบรารีที่ John 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 ในรหัสที่ฉันให้ไว้ในคำตอบของฉัน ;-)
John Slegers

2

รหัส

Gist โดย Eldon McGuinnessนี้เป็นการใช้งานตัวแยกวิเคราะห์สตริงการสืบค้น JavaScript ที่สมบูรณ์แบบที่สุดเท่าที่ฉันเคยเห็นมา

น่าเสียดายที่มันเขียนเป็นปลั๊กอิน jQuery

ฉันเขียนใหม่เป็น vanilla 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

ฟังก์ชั่นที่ฉันเขียนสำหรับความต้องการที่คล้ายกับสิ่งนี้ด้วยการจัดการสตริงจาวาสคริปต์ล้วนๆ

"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

เพียงการปรับปรุงเล็กน้อย วิธีการที่ใช้ทำให้ง่ายสำหรับผู้ใช้ ผู้ใช้เพียงต้องการทราบว่าเขาต้องการค่าสตริงคำค้นหาใด
Pranavan Maru

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
ฉันไม่มั่นใจว่าคุณต้องการห้องสมุดจริงๆเพื่อทำจำนวนโค้ดสามบรรทัดด้านบน! อย่างน้อยคุณก็หวังว่าไลบรารีจะจำตัวถอดรหัสURIComponent () ได้ทั้งคีย์และค่าบางสิ่งบางอย่างที่โค้ดทั้งหมดโพสต์จนถึงตอนนี้ล้มเหลว
bobince

คุณไม่จำเป็นต้องมีห้องสมุด ฉันต้องการเปรียบเทียบการใช้งานของฉันกับการใช้งานในไลบรารีเพื่อที่ฉันจะได้ดูว่าฉันพลาดเคส Edge หรือไม่ :)
หลัก

javascript ไม่ใช่ภาษาแม่ของคุณหมายความว่าอย่างไรคุณควรเรียนรู้แม้ว่าคุณจะต้องการห้องสมุดเพื่อใช้ก็ตาม
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']

การชนะในที่นี้คืออินเทอร์เฟซเชิงวัตถุ (แทนที่จะเป็นฟังก์ชัน) และสามารถทำได้กับสตริงใด ๆ (ไม่ใช่เฉพาะตำแหน่งค้นหา)

หากคุณใช้ไลบรารี JavaScript อยู่แล้วฟังก์ชันนี้จะมีอยู่แล้ว ตัวอย่างเช่นนี่คือเวอร์ชันของ Prototype

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.