ฉันจะรับค่าสตริงข้อความค้นหาใน JavaScript ได้อย่างไร


2697

มีวิธีที่ปลั๊กอินน้อยกว่าในการดึงค่าสตริงแบบสอบถามผ่าน jQuery (หรือไม่)?

ถ้าเป็นเช่นนั้นได้อย่างไร ถ้าไม่มีปลั๊กอินที่สามารถทำได้หรือไม่


ผมใช้ปลั๊กอินgetUrlParamอธิบายไว้ในjQuery ปลั๊กอิน - getUrlParam (รุ่น 2)
coma

69
จาวาสคริปต์ธรรมดาวิธีการแก้ปัญหาโดยไม่ต้อง RegEx: css-tricks.com/snippets/javascript/get-url-variables
ลอเรน Polidori

6
แม้ว่าโซลูชันบนสุดสำหรับคำถามนั้นควรได้รับความนิยมเนื่องจากการสังเกตที่ยอดเยี่ยมว่าไม่จำเป็นต้องใช้ jQuery แต่วิธีการในการสร้างนิพจน์ทั่วไปใหม่และการแยกวิเคราะห์สตริงข้อความค้นหาใหม่สำหรับทุกพารามิเตอร์ที่ต้องการนั้นไม่มีประสิทธิภาพอย่างมาก โซลูชันที่มีประสิทธิภาพมากขึ้น (และหลากหลาย) มีอยู่เป็นเวลานานตัวอย่างเช่นในบทความนี้พิมพ์ซ้ำที่นี่: htmlgoodies.com/beyond/javascript/article.php/11877_3755006_3/ …
Joseph Myers

1
อาจเป็นไปได้ซ้ำกับสตริงข้อความค้นหา JavaScript

4
โจเซฟ "การสังเกตที่ยอดเยี่ยมที่ไม่จำเป็นต้องใช้ jQuery"? แน่นอนว่ามันไม่จำเป็น ทุกสิ่งที่ jQuery ทำก็ใช้ JavaScript ผู้ใช้ไม่ได้ใช้ jQuery เพราะทำสิ่งที่ JavaScript ไม่สามารถทำได้ ประเด็นของ jQuery คือความสะดวกสบาย
Vladimir Kornea

คำตอบ:


8323

อัปเดต: Sep-2018

คุณสามารถใช้URLSearchParamsซึ่งเรียบง่ายและรองรับเบราว์เซอร์ (แต่ไม่สมบูรณ์) ที่เหมาะสม

const urlParams = new URLSearchParams(window.location.search);
const myParam = urlParams.get('myParam');

เป็นต้นฉบับ

คุณไม่ต้องการ jQuery เพื่อจุดประสงค์นั้น คุณสามารถใช้จาวาสคริปต์ที่บริสุทธิ์ได้:

function getParameterByName(name, url) {
    if (!url) url = window.location.href;
    name = name.replace(/[\[\]]/g, '\\$&');
    var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
        results = regex.exec(url);
    if (!results) return null;
    if (!results[2]) return '';
    return decodeURIComponent(results[2].replace(/\+/g, ' '));
}

การใช้งาน:

// query string: ?foo=lorem&bar=&baz
var foo = getParameterByName('foo'); // "lorem"
var bar = getParameterByName('bar'); // "" (present with empty value)
var baz = getParameterByName('baz'); // "" (present with no value)
var qux = getParameterByName('qux'); // null (absent)


หมายเหตุ: หากพารามิเตอร์มีอยู่หลายครั้ง ( ?foo=lorem&foo=ipsum) คุณจะได้รับค่าแรก ( lorem) มีมาตรฐานเกี่ยวกับเรื่องนี้และประเพณีแตกต่างกันไปดูตัวอย่างคำถามนี้: ตำแหน่งเผด็จการของคีย์ซ้ำ HTTP GET แบบสอบถาม
หมายเหตุ: ฟังก์ชั่นนั้นต้องตรงตามตัวพิมพ์ใหญ่ - เล็ก หากคุณต้องการชื่อพารามิเตอร์ที่ไม่ต้องตรงตามตัวพิมพ์ใหญ่และตัวพิมพ์ใหญ่ให้เพิ่มตัวปรับแต่ง 'i' ใน RegExp


นี่คือการอัปเดตตามข้อกำหนดใหม่ของURLSearchParamsเพื่อให้ได้ผลลัพธ์เดียวกันโดยสังเขป ดูคำตอบที่ชื่อ " URLSearchParams " ด้านล่าง


131
ฟังก์ชั่นนี้จัดการอย่างไรhttp://www.mysite.com/index.php?x=x1&x=x2&x=x3ค่าของเขตข้อมูลxไม่ชัดเจน
dpp

94
สิ่งนี้ยังไม่สามารถจัดการกับคีย์ที่มีค่าหลายค่าซึ่งยังถูกกฎหมายอย่างสมบูรณ์
hurrymaplelad

17
ทำไมคุณต้องใช้นิพจน์ทั่วไปสำหรับสิ่งนี้
Ry-

28
สำหรับสตริงการสืบค้นของ?mykey=0&m.+key=1โทรgetParameterByName("m.+key")จะกลับมาแทน0 1คุณต้องหลีกเลี่ยง metacharacters นิพจน์ปกติnameก่อนที่จะสร้างนิพจน์ปกติของคุณ และคุณต้องโทร.replace()เพียงครั้งเดียวโดยใช้ค่าสถานะโกลบอลและใช้"\\$&"เป็นนิพจน์แทน คุณควรค้นหาบนแทนlocation.search location.hrefคำตอบที่มีผู้โหวตเกิน 400 คนควรพิจารณารายละเอียดเหล่านี้
gilly3

7
คุณไม่จำเป็นต้องใช้ jQuery เพื่อวัตถุประสงค์นั้นหรือเพื่อวัตถุประสงค์อื่น คุณไม่ต้องการมันจริงๆ
gztomas

1708

โซลูชันบางรายการที่โพสต์ที่นี่ไม่มีประสิทธิภาพ ทำซ้ำการค้นหานิพจน์ปกติทุกครั้งที่สคริปต์จำเป็นต้องเข้าถึงพารามิเตอร์นั้นไม่จำเป็นทั้งหมดฟังก์ชันหนึ่งเดียวเพื่อแยกพารามิเตอร์เป็นวัตถุสไตล์อาเรย์แบบเชื่อมโยงนั้นก็เพียงพอแล้ว หากคุณไม่ได้ทำงานกับ API ประวัติ HTML 5 สิ่งนี้จำเป็นเพียงครั้งเดียวต่อการโหลดหน้าเว็บ คำแนะนำอื่น ๆ ที่นี่ยังไม่สามารถถอดรหัส URL ได้อย่างถูกต้อง

var urlParams;
(window.onpopstate = function () {
    var match,
        pl     = /\+/g,  // Regex for replacing addition symbol with a space
        search = /([^&=]+)=?([^&]*)/g,
        decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); },
        query  = window.location.search.substring(1);

    urlParams = {};
    while (match = search.exec(query))
       urlParams[decode(match[1])] = decode(match[2]);
})();

ตัวอย่างการสืบค้น:

?i=main&mode=front&sid=de8d49b78a85a322c4155015fdce22c4&enc=+Hello%20&empty

ผลลัพธ์:

 urlParams = {
    enc: " Hello ",
    i: "main",
    mode: "front",
    sid: "de8d49b78a85a322c4155015fdce22c4",
    empty: ""
}

alert(urlParams["mode"]);
// -> "front"

alert("empty" in urlParams);
// -> true

สิ่งนี้สามารถปรับปรุงได้อย่างง่ายดายเพื่อจัดการกับสตริงการสืบค้นในสไตล์อาร์เรย์เช่นกัน ตัวอย่างของสิ่งนี้อยู่ที่นี่แต่เนื่องจากพารามิเตอร์สไตล์อาเรย์ไม่ได้กำหนดไว้ในRFC 3986ฉันจะไม่สร้างคำตอบให้กับซอร์สโค้ด สำหรับผู้ที่สนใจใน "ปนเปื้อน" รุ่นดูที่คำตอบ campbeln ด้านล่าง

นอกจากนี้ตามที่ระบุไว้ในความคิดเห็น;เป็นตัวคั่นทางกฎหมายสำหรับkey=valueคู่ มันจะต้องใช้ regex ที่ซับซ้อนมากขึ้นในการจัดการ;หรือ&ซึ่งฉันคิดว่าไม่จำเป็นเพราะมันหายากที่;ใช้และฉันจะบอกว่าไม่น่าที่จะใช้ทั้งสองอย่าง หากคุณต้องการการสนับสนุน;แทน&เพียงแค่เปลี่ยนพวกเขาใน regex


หากคุณใช้ภาษาที่ประมวลผลล่วงหน้าฝั่งเซิร์ฟเวอร์คุณอาจต้องการใช้ฟังก์ชัน JSON ดั้งเดิมเพื่อยกระดับอย่างหนักสำหรับคุณ ตัวอย่างเช่นใน PHP คุณสามารถเขียน:

<script>var urlParams = <?php echo json_encode($_GET, JSON_HEX_TAG);?>;</script>

ง่ายกว่ามาก!

ปรับปรุง

ความสามารถใหม่ที่จะดึง params myparam=1&myparam=2ซ้ำเป็นดังต่อไปนี้ ไม่มีสเปคอย่างไรก็ตามวิธีการปัจจุบันส่วนใหญ่เป็นไปตามการสร้างอาร์เรย์

myparam = ["1", "2"]

ดังนั้นนี่คือวิธีการจัดการ:

let urlParams = {};
(window.onpopstate = function () {
    let match,
        pl = /\+/g,  // Regex for replacing addition symbol with a space
        search = /([^&=]+)=?([^&]*)/g,
        decode = function (s) {
            return decodeURIComponent(s.replace(pl, " "));
        },
        query = window.location.search.substring(1);

    while (match = search.exec(query)) {
        if (decode(match[1]) in urlParams) {
            if (!Array.isArray(urlParams[decode(match[1])])) {
                urlParams[decode(match[1])] = [urlParams[decode(match[1])]];
            }
            urlParams[decode(match[1])].push(decode(match[2]));
        } else {
            urlParams[decode(match[1])] = decode(match[2]);
        }
    }
})();

11
หากคุณกำลังทำแอพ ajax ที่หนักหน่วงคุณอาจใช้แฮช (#) เพื่อ "เปิดใช้งานปุ่มย้อนกลับ" ... ในกรณีนั้นการสอบถามจะเปลี่ยนตลอดเวลา (ดูว่า Facebook ทำอย่างไร) .. แต่วิธีการเหล่านี้จะไม่สนใจสิ่งที่มาหลังจาก anways # ... การ
นิค Franceschina

100
@Nick: มีอะไรหลังจากแฮชอยู่ในwindow.location.hashคุณสมบัติซึ่งแยกต่างหากจากwindow.location.searchคุณสมบัติ หากแฮชเปลี่ยนแปลงจะไม่มีผลกับการสอบถามเลย
Andy E

27
อย่าลืมว่า;เป็นตัวคั่นทางกฎหมายสำหรับkey=valueคู่GET หายาก แต่ใช้เวลา 5 วินาทีในการติดตั้ง
alex

4
เพื่อความเป็นธรรมไม่มีการกำหนดรูปแบบเฉพาะสำหรับสตริงการสืบค้นโดย RFC3986 ?a=b&c=dเป็นแบบธรรมดาและคำแนะนำ W3C สำหรับแบบฟอร์มบนเว็บ แต่ข้อกำหนด URI นั้นกำหนดquery = *( pchar / "/" / "?" )ไว้
Matthew Gilliard

21
สำหรับพวกเราที่ใช้เซ็ตอัพ JSHint ค่อนข้างเข้มงวดสลับwhile(match = search.exec(query))กับwhile((match = search.exec(query)) !== null)
craigts

1283

ES2015 (ES6)

getQueryStringParams = query => {
    return query
        ? (/^[?#]/.test(query) ? query.slice(1) : query)
            .split('&')
            .reduce((params, param) => {
                    let [key, value] = param.split('=');
                    params[key] = value ? decodeURIComponent(value.replace(/\+/g, ' ')) : '';
                    return params;
                }, {}
            )
        : {}
};

ไม่มี jQuery

var qs = (function(a) {
    if (a == "") return {};
    var b = {};
    for (var i = 0; i < a.length; ++i)
    {
        var p=a[i].split('=', 2);
        if (p.length == 1)
            b[p[0]] = "";
        else
            b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
    }
    return b;
})(window.location.search.substr(1).split('&'));

ด้วย URL เช่น?topic=123&name=query+stringนี้จะกลับมา:

qs["topic"];    // 123
qs["name"];     // query string
qs["nothere"];  // undefined (object)

วิธีการของ Google

ฉีกรหัสของ Google ฉันพบวิธีที่พวกเขาใช้: getUrlParameters

function (b) {
    var c = typeof b === "undefined";
    if (a !== h && c) return a;
    for (var d = {}, b = b || k[B][vb], e = b[p]("?"), f = b[p]("#"), b = (f === -1 ? b[Ya](e + 1) : [b[Ya](e + 1, f - e - 1), "&", b[Ya](f + 1)][K](""))[z]("&"), e = i.dd ? ia : unescape, f = 0, g = b[w]; f < g; ++f) {
        var l = b[f][p]("=");
        if (l !== -1) {
            var q = b[f][I](0, l),
                l = b[f][I](l + 1),
                l = l[Ca](/\+/g, " ");
            try {
                d[q] = e(l)
            } catch (A) {}
        }
    }
    c && (a = d);
    return d
}

มันทำให้งง แต่ก็เข้าใจได้ มันไม่ทำงานเพราะตัวแปรบางอย่างไม่ได้กำหนด

พวกเขาเริ่มต้นที่จะมองหาพารามิเตอร์ใน URL จากและจากกัญชา? #จากนั้นสำหรับแต่ละพารามิเตอร์ที่พวกเขาแบ่งในเครื่องหมายเท่ากับb[f][p]("=")(ซึ่งดูเหมือนว่าindexOfพวกเขาใช้ตำแหน่งของถ่านเพื่อรับคีย์ / ค่า) ให้แยกพวกเขาตรวจสอบว่าพารามิเตอร์มีค่าหรือไม่หากมีพวกเขาก็เก็บค่าdพวกเขาเพียงแค่ดำเนินการต่อ

ในที่สุดวัตถุdจะถูกส่งกลับการจัดการการหลบหนีและ+สัญญาณ วัตถุนี้เหมือนกับของฉันมันมีพฤติกรรมแบบเดียวกัน


วิธีการของฉันเป็นปลั๊กอิน jQuery

(function($) {
    $.QueryString = (function(paramsArray) {
        let params = {};

        for (let i = 0; i < paramsArray.length; ++i)
        {
            let param = paramsArray[i]
                .split('=', 2);

            if (param.length !== 2)
                continue;

            params[param[0]] = decodeURIComponent(param[1].replace(/\+/g, " "));
        }

        return params;
    })(window.location.search.substr(1).split('&'))
})(jQuery);

การใช้

//Get a param
$.QueryString.param
//-or-
$.QueryString["param"]
//This outputs something like...
//"val"

//Get all params as object
$.QueryString
//This outputs something like...
//Object { param: "val", param2: "val" }

//Set a param (only in the $.QueryString object, doesn't affect the browser's querystring)
$.QueryString.param = "newvalue"
//This doesn't output anything, it just updates the $.QueryString object

//Convert object into string suitable for url a querystring (Requires jQuery)
$.param($.QueryString)
//This outputs something like...
//"param=newvalue&param2=val"

//Update the url/querystring in the browser's location bar with the $.QueryString object
history.replaceState({}, '', "?" + $.param($.QueryString));
//-or-
history.pushState({}, '', "?" + $.param($.QueryString));

การทดสอบประสิทธิภาพ (วิธีแยกกับวิธี regex) ( jsPerf )

รหัสการเตรียมการ: การประกาศเมธอด

แยกรหัสทดสอบ

var qs = window.GetQueryString(query);

var search = qs["q"];
var value = qs["value"];
var undef = qs["undefinedstring"];

รหัสทดสอบ Regex

var search = window.getParameterByName("q");
var value = window.getParameterByName("value");
var undef = window.getParameterByName("undefinedstring");

การทดสอบใน Firefox 4.0 x86 บน Windows Server 2008 R2 / 7 x64

  • วิธีการแยก : เร็วที่สุด 144,780 ± 2.17%
  • วิธี Regex : 13,891 ± 0.85% | ช้าลง 90%

1
นี่เป็นวิธีการที่ดีวิธีแยกสตริงแทนที่จะใช้นิพจน์ทั่วไป มีบางสิ่งที่ควรค่าแก่การชี้ถึงแม้ว่า :-) 1. unescapeเป็นฟังก์ชันที่เลิกใช้แล้วและถูกแทนที่ด้วยdecodeURIComponent()โปรดทราบว่าฟังก์ชั่นเหล่านี้จะไม่ถอดรหัสเป็น+อักขระเว้นวรรคอย่างถูกต้อง 2. คุณควรประกาศผลลัพธ์เป็นวัตถุแทนที่จะเป็นอาเรย์เนื่องจาก JavaScript ไม่มีอาเรย์แบบเชื่อมโยงต่อ se และอาเรย์ที่คุณประกาศนั้นจะถือว่าเป็นวัตถุโดยการกำหนดคุณสมบัติที่มีชื่อให้กับมันอย่างไรก็ตาม
Andy E

55
อยากรู้ว่าทำไมคุณถึงทำให้ปลั๊กอินนี้เป็น jQuery เมื่อมันไม่มีรหัสเฉพาะของ jQuery?
zachleat

63
@zachleat หากคุณไม่มีกรอบงานของคุณฟังก์ชันของคุณจะแพร่กระจายไปทั่วโค้ดของคุณ หากคุณขยาย jQuery คุณจะมีขอบเขตสำหรับฟังก์ชั่นของคุณมันจะไม่ลอยไปไหนมาไหนในรหัสของคุณ ฉันคิดว่านั่นเป็นเหตุผลเดียว
BrunoLM

6
นี่คือเวอร์ชัน jQuery ที่ปรับแต่งให้ผ่านJSLint (อย่างน้อยเป้าหมายกึ่งเคลื่อนไหวของ JSLint.com เมื่อ 2011-06-15) ส่วนใหญ่เป็นเพียงการเคลื่อนย้ายสิ่งต่าง ๆ รอบ ๆ เพื่อเอาใจ The Crockford
patridge

3
@BenjaminGruenbaum พูดติดตลกฉันก็ไม่ค่อยเห็นประเด็นในการเปรียบเทียบประสิทธิภาพการแยกวิเคราะห์ URL หากสิ่งนี้ถูกสร้างขึ้นในโมดูล isomorphic JavaScript ที่สามารถเรียกใช้จากโหนดไปยังให้พูดแยกวิเคราะห์ล็อกแล้วใช่ แต่การใช้เพื่อแยกพารามิเตอร์ URL window.locationทำให้ประสิทธิภาพเป็นกังวลเกี่ยวกับประสิทธิภาพเนื่องจากไคลเอนต์ที่นำทางไปยัง URL นั้นไกลมากแพงกว่า
Dan Dascalescu

659

คำตอบของArtem Bargerรุ่นปรับปรุง:

function getParameterByName(name) {
    var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
    return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
}

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการปรับปรุงโปรดดู: http://james.padolsey.com/javascript/bujs-1-getparameterbyname/


23
หากคุณต้องการที่จะตัดให้สั้นลงอีกเล็กน้อยที่คุณสามารถทำไปด้วยประกอบไปด้วยเงื่อนไขและแทนที่ด้วยบิตของสั้นวงจรในบรรทัดสุดท้ายที่ return match && decodeURIComponent(match[1].replace(/\+/g, ' '));-
Andy E

มันจะส่งคืนnullถ้าพารามิเตอร์ไม่ได้ตามด้วย '=' คุณสามารถเสริมif (!RegExp('[?&]'+name+'(&.*)?$').exec(window.location.search)) return false;เพื่อทำให้มันกลับมาboolean falseถ้าพารามิเตอร์ไม่ได้มีเลย
commonpike

9
ฉันจะใช้newคำนำหน้าเมื่อสร้าง regex:var match = new RegExp('...
Patrick Berkeley

2
ข้อผิดพลาด IE11: IE ตัดสินใจที่จะเติมค่าที่ส่งคืนด้วยอักขระ ASCII 8206 (ฐานสิบหก: 200E - "อักขระจากซ้ายไปขวา") ฉันเสียเวลาไปมากกว่า 6 ชั่วโมงในการค้นหาสิ่งนี้! การระบายการรักษา .... เพื่อแก้ไขตะปูถึงจุดสิ้นสุดของบรรทัดสุดท้าย:.replace('\u200E', '')
JayRO-GreyBeard

อย่างน้อยใน Chrome บน mac (อาจเป็นเบราว์เซอร์อื่นด้วย) ค่าสุดท้ายได้รับ '/' ต่อท้าย ดังนั้นฉันจึงปรับเปลี่ยน regex ให้เพิกเฉย var results = new RegExp('[\\?&]' + name + '=([^&#/]*)').exec(url);
CaseyB

594

URLSearchParams

Firefox 44+, Opera 36+, Edge 17+, Safari 10.3+ และ Chrome 49+รองรับURLSearchParams API:

มีURLSearchParams polyfill ที่แนะนำโดยGoogleสำหรับ IE เวอร์ชันที่เสถียร

มันไม่ได้เป็นมาตรฐานโดยW3Cแต่เป็นมาตรฐานการดำรงชีวิตโดยWhatWG WHATWG

คุณสามารถใช้กับlocation:

let params = new URLSearchParams(location.search);

หรือ

let params = (new URL(location)).searchParams;

หรือแน่นอนใน URL ใด ๆ :

let url = new URL('https://example.com?foo=1&bar=2');
let params = new URLSearchParams(url.search);

คุณสามารถรับพารามิเตอร์ได้โดยใช้.searchParamsคุณสมบัติชวเลขบนวัตถุ URL เช่นนี้:

let params = new URL('https://example.com?foo=1&bar=2').searchParams;
params.get('foo'); // "1"
params.get('bar'); // "2" 

คุณอ่าน / ตั้งค่าพารามิเตอร์ผ่านget(KEY), set(KEY, VALUE), append(KEY, VALUE)API คุณยังสามารถวนซ้ำค่าทั้งหมดได้for (let p of params) {}ได้

ดำเนินการอ้างอิงและหน้าตัวอย่างที่มีอยู่สำหรับการตรวจสอบและการทดสอบ


ทั้งสอง downvoters อาจพลาด (เหมือนที่ฉันเพิ่งทำ) ความจริงที่ว่าคุณต้องใช้.getแทนเพียงแค่.
Nakilon

20
คุณไม่จำเป็นต้องslice(1)เปิด.searchใช้งานจริงคุณสามารถใช้งานได้โดยตรง URLSearchParams ?สามารถจัดการชั้นนำ
Jason C

URLSearchParamsไม่ดีเนื่องจากไม่ส่งคืนค่าจริงของพารามิเตอร์ของ URL
Melab

สิ่งนี้new URL('https://example.com?foo=1&bar=2') ไม่ทำงานสำหรับ android urlfile:///android_asset/...
shah

@Melab มันยังดีที่มันให้ API ง่าย ๆ สำหรับ regexing แปลก ๆ ในคำตอบอื่น ๆ ที่นี่ แต่มันก็แปลกสำหรับฉันที่ id ไม่ได้ทำ window.location.search ตามค่าเริ่มต้นและไม่มีวิธีการอัปเดต URL ปัจจุบันที่รวมอยู่
Damon

400

เพียงแค่คำแนะนำอื่น ปลั๊กอินPurlอนุญาตให้เรียกคืนทุกส่วนของ URL รวมถึงจุดยึดโฮสต์ ฯลฯ

มันสามารถใช้งานได้โดยมีหรือไม่มี jQuery

การใช้งานง่ายและยอดเยี่ยม:

var url = $.url('http://allmarkedup.com/folder/dir/index.html?item=value'); // jQuery version
var url = purl('http://allmarkedup.com/folder/dir/index.html?item=value'); // plain JS version
url.attr('protocol'); // returns 'http'
url.attr('path'); // returns '/folder/dir/index.html'

อย่างไรก็ตาม ณ วันที่ 11 พ.ย. 2014 Purl ไม่ได้รับการดูแลรักษาอีกต่อไปและผู้เขียนแนะนำให้ใช้URI.jsแทน ปลั๊กอิน jQuery นั้นแตกต่างกันโดยจะเน้นที่องค์ประกอบต่างๆ - สำหรับการใช้งานกับสตริงเพียงใช้URIโดยตรงโดยมีหรือไม่มี jQuery รหัสที่คล้ายกันจะมีลักษณะเช่นนี้เอกสารฉบับเต็มที่นี่ :

var url = new URI('http://allmarkedup.com/folder/dir/index.html?item=value'); // plain JS version
url.protocol(); // returns 'http'
url.path(); // returns '/folder/dir/index.html'

7
ในขณะที่การเขียนน้ำวนไม่ได้รับการบำรุงรักษาอีกต่อไปและผู้ดูแลระบบคนก่อนหน้านี้แนะนำuri.js
Dan Pantry

238

TL; DR

รวดเร็ว, โซลูชั่นที่สมบูรณ์ซึ่งจับหลายค่าปุ่มและตัวอักษรที่เข้ารหัส

var qd = {};
if (location.search) location.search.substr(1).split("&").forEach(function(item) {var s = item.split("="), k = s[0], v = s[1] && decodeURIComponent(s[1]); (qd[k] = qd[k] || []).push(v)})

//using ES6   (23 characters cooler)
var qd = {};
if (location.search) location.search.substr(1).split`&`.forEach(item => {let [k,v] = item.split`=`; v = v && decodeURIComponent(v); (qd[k] = qd[k] || []).push(v)})
Multi-เรียงราย:
var qd = {};
if (location.search) location.search.substr(1).split("&").forEach(function(item) {
    var s = item.split("="),
        k = s[0],
        v = s[1] && decodeURIComponent(s[1]); //  null-coalescing / short-circuit
    //(k in qd) ? qd[k].push(v) : qd[k] = [v]
    (qd[k] = qd[k] || []).push(v) // null-coalescing / short-circuit
})

รหัสทั้งหมดนี้คืออะไร ...
"null-coalescing" , การประเมินผลแบบลัดวงจร
ES6 การกำหนดค่าการทำลายโครงสร้าง , ฟังก์ชัน Arrow , สตริงเทมเพลต

ตัวอย่าง:
"?a=1&b=0&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"
> qd
a: ["1", "5", "t e x t"]
b: ["0"]
c: ["3"]
d: [undefined]
e: [undefined, "http://w3schools.com/my test.asp?name=ståle&car=saab"]

> qd.a[1]    // "5"
> qd["a"][1] // "5"



อ่านเพิ่มเติม ... เกี่ยวกับโซลูชัน Vanilla JavaScript

ในการเข้าถึงส่วนต่างๆของ URL ให้ใช้ location.(search|hash)

วิธีแก้ปัญหาที่ง่ายที่สุด (จำลอง)

var queryDict = {};
location.search.substr(1).split("&").forEach(function(item) {queryDict[item.split("=")[0]] = item.split("=")[1]})
  • จัดการกับคีย์ว่างได้อย่างถูกต้อง
  • แทนที่คีย์หลายคีย์พร้อมค่าสุดท้ายที่พบ
"?a=1&b=0&c=3&d&e&a=5"
> queryDict
a: "5"
b: "0"
c: "3"
d: undefined
e: undefined

กุญแจหลายค่า

ตรวจสอบคีย์อย่างง่าย (item in dict) ? dict.item.push(val) : dict.item = [val]

var qd = {};
location.search.substr(1).split("&").forEach(function(item) {(item.split("=")[0] in qd) ? qd[item.split("=")[0]].push(item.split("=")[1]) : qd[item.split("=")[0]] = [item.split("=")[1]]})
  • ตอนนี้ส่งกลับอาร์เรย์แทน
  • เข้าถึงค่าโดยqd.key[index]หรือqd[key][index]
> qd
a: ["1", "5"]
b: ["0"]
c: ["3"]
d: [undefined]
e: [undefined]

อักขระที่เข้ารหัส?

ใช้decodeURIComponent()สำหรับการแยกที่สองหรือทั้งสอง

var qd = {};
location.search.substr(1).split("&").forEach(function(item) {var k = item.split("=")[0], v = decodeURIComponent(item.split("=")[1]); (k in qd) ? qd[k].push(v) : qd[k] = [v]})
ตัวอย่าง:
"?a=1&b=0&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"
> qd
a: ["1", "5", "t e x t"]
b: ["0"]
c: ["3"]
d: ["undefined"]  // decodeURIComponent(undefined) returns "undefined" !!!*
e: ["undefined", "http://w3schools.com/my test.asp?name=ståle&car=saab"]



จากความคิดเห็น

* !!! โปรดทราบว่าสตริงผลตอบแทนdecodeURIComponent(undefined) "undefined"วิธีการแก้ปัญหาอยู่ในการใช้งานง่าย&&ซึ่งทำให้มั่นใจได้ว่าdecodeURIComponent()จะไม่เรียกว่าค่าไม่ได้กำหนด (ดู "โซลูชันที่สมบูรณ์" ที่ด้านบน)

v = v && decodeURIComponent(v);


ถ้าสตริงการสืบค้นว่างเปล่า ( location.search == "") qd == {"": undefined}ผลที่ได้คือค่อนข้างทำให้เข้าใจผิด ขอแนะนำให้ตรวจสอบการสอบถามก่อนที่จะเปิดใช้งานฟังก์ชันการแยกวิเคราะห์ Likeo:

if (location.search) location.search.substr(1).split("&").forEach(...)

1
ดี สิ่งเดียวที่ฉันจะเปลี่ยน - คือถ้าไม่มีค่ามากกว่าหนึ่งค่าสำหรับคีย์ไม่จำเป็นต้องให้มันเป็นอาร์เรย์ ใช้อาร์เรย์เท่านั้นหากมีมากกว่าหนึ่งค่าต่อหนึ่งคีย์
Pavel Nikolov

2
@PavelNikolov ฉันคิดว่ามันจะแนะนำความยากลำบากในการรับอาร์เรย์บางครั้งและบางครั้งก็มีค่า คุณจะต้องตรวจสอบมันก่อนตอนนี้คุณจะตรวจสอบความยาวเพราะคุณจะใช้รอบในการดึงค่าเหล่านั้นต่อไป นอกจากนี้ยังหมายถึงการแก้ปัญหาที่ง่ายที่สุด แต่ใช้งานได้ที่นี่
Qwerty

@katsh ใช่มันใช้งานได้ใน> = IE9 อย่างไรก็ตามคุณสามารถสอนตัวประมวลผลจาวาสคริปต์ของคุณได้array.forEach()โดยการฉีดรหัสที่จุดเริ่มต้นของสคริปต์ของคุณ ดูนักพัฒนา
Qwerty

1
แผ่ออกเล็กน้อยเพื่อให้สามารถอ่านได้ทำในฟังก์ชั่นและนำมาใช้อีกสายแยก: function parseQueryString () {var qd = {}; location.search.substr (1) .split ("&"). forEach (ฟังก์ชั่น (รายการ) {var parts = item.split ("="); var k = ส่วน [0]; var v = decodeURIComponent (ส่วน [ 1]); (k ใน qd)? qd [k] .push (v): qd [k] = [v,]}); ส่งคืน qd; }
Casey

1
decodeDocumentURI (undefined) ส่งคืน "undefined" แทน undefined แพทช์ที่ใช้งานได้ แต่ไม่ค่อยหรูหรา: var qd = {}; location.search.substr(1).split("&").forEach( function(item) { var s = item.split("="), k = s[0], v; if(s.length>1) v = decodeURIComponent(s[1]); (k in qd) ? qd[k].push(v) : qd[k] = [v] })
วน

218

Roshambo บน snipplr.com มีสคริปต์ง่าย ๆ เพื่อให้บรรลุตามที่อธิบายไว้ในรับพารามิเตอร์ URL ด้วย jQuery | ปรับปรุงแล้ว ด้วยสคริปต์ของเขาคุณสามารถดึงพารามิเตอร์ที่คุณต้องการได้อย่างง่ายดาย

นี่คือส่วนสำคัญ:

$.urlParam = function(name, url) {
    if (!url) {
     url = window.location.href;
    }
    var results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(url);
    if (!results) { 
        return undefined;
    }
    return results[1] || undefined;
}

จากนั้นก็รับพารามิเตอร์ของคุณจากสตริงการสืบค้น

ดังนั้นถ้าสตริง / URL xyz.com/index.html?lang=deแบบสอบถามเป็น

เพียงแค่โทรหาvar langval = $.urlParam('lang');แล้วคุณจะได้รับ

UZBEKJON มีการโพสต์บล็อกที่ดีเกี่ยวกับเรื่องนี้เป็นอย่างดีรับพารามิเตอร์และค่า URL กับ jQuery


13
กับ jQueryดูเหมือนจะหมายถึงการ namespace ฟังก์ชั่นเพื่อวัตถุ jQuery นอกจากนี้ทำไมค่าที่ไม่ถูกต้อง0คืออะไร? แน่นอนว่าฉันสามารถใช้การตรวจสอบความเท่าเทียมกันอย่างเข้มงวด แต่ไม่ควรnullใช่หรือไม่
alex

ตกลง มันทำงานได้เหมือนการอ้างอิงตัวแปร javascript ปกติด้วยวิธีนั้น (ยกเว้นการส่งคืนที่ไม่ได้กำหนดจะมีความแม่นยำมากกว่า)
Isochronous

'ชื่อ' ไม่ได้รับการหลบหนีอย่างเหมาะสมมันเป็นเพียงการฉีดเข้าไปยัง RegExp โดยตรง สิ่งนี้ล้มเหลว เช่นเดียวกับคนอื่น ๆ ที่กล่าวว่ามันเป็นคำตอบที่ไม่น่าเชื่อเหล่านี้คือการสร้างวงล้อใหม่และได้รับคะแนนเสียงมากมายเมื่อสิ่งนี้ควรถูกนำไปใช้ในห้องสมุดที่ผ่านการทดสอบมาอย่างดี
Triynko

167

หากคุณกำลังใช้ jQuery คุณสามารถใช้ห้องสมุดเช่นjQuery บาร์บีคิว: ปุ่มย้อนกลับและห้องสมุดแบบสอบถาม

... jQuery BBQ ให้.deparam()วิธีการเต็มรูปแบบพร้อมกับทั้งการจัดการสถานะแฮชและการแยกส่วนสตริง / แบบสอบถามแบบสอบถามและวิธีการผสานยูทิลิตี้

แก้ไข: การเพิ่มตัวอย่าง Deparam:

 var DeparamExample = function() {
            var params = $.deparam.querystring();

            //nameofparam is the name of a param from url
            //code below will get param if ajax refresh with hash
            if (typeof params.nameofparam == 'undefined') {
                params = jQuery.deparam.fragment(window.location.href);
            }
            
            if (typeof params.nameofparam != 'undefined') {
                var paramValue = params.nameofparam.toString();
                  
            }
        };

หากคุณต้องการใช้ JavaScript ธรรมดาคุณสามารถใช้ ...

var getParamValue = (function() {
    var params;
    var resetParams = function() {
            var query = window.location.search;
            var regex = /[?&;](.+?)=([^&;]+)/g;
            var match;

            params = {};

            if (query) {
                while (match = regex.exec(query)) {
                    params[match[1]] = decodeURIComponent(match[2]);
                }
            }    
        };

    window.addEventListener
    && window.addEventListener('popstate', resetParams);

    resetParams();

    return function(param) {
        return params.hasOwnProperty(param) ? params[param] : null;
    }

})();​

เนื่องจาก API ประวัติ HTML ใหม่และโดยเฉพาะhistory.pushState()และhistory.replaceState()URL สามารถเปลี่ยนได้ซึ่งจะทำให้แคชของพารามิเตอร์และค่าของพวกเขาไม่ถูกต้อง

รุ่นนี้จะอัพเดตแคชภายในของพารามิเตอร์ทุกครั้งที่มีการเปลี่ยนแปลงประวัติ


100

เพียงใช้สองแยก :

function get(n) {
    var half = location.search.split(n + '=')[1];
    return half !== undefined ? decodeURIComponent(half.split('&')[0]) : null;
}

ฉันอ่านคำตอบก่อนหน้านี้และคำตอบที่สมบูรณ์มากขึ้นทั้งหมด แต่ฉันคิดว่านั่นเป็นวิธีที่ง่ายและเร็วที่สุด คุณสามารถตรวจสอบในเกณฑ์มาตรฐาน jsPerf นี้

เพื่อแก้ปัญหาในความคิดเห็นของรูเพิ่งให้เพิ่มการแบ่งตามเงื่อนไขโดยเปลี่ยนบรรทัดแรกเป็นสองบรรทัดด้านล่าง แต่ความถูกต้องสมบูรณ์หมายถึงตอนนี้ช้ากว่า regexp (ดูjsPerf )

function get(n) {
    var half = location.search.split('&' + n + '=')[1];
    if (!half) half = location.search.split('?' + n + '=')[1];
    return half !== undefined ? decodeURIComponent(half.split('&')[0]) : null;
}

ดังนั้นหากคุณรู้ว่าคุณจะไม่เจอกรณีพิพาทของรูปีสิ่งนี้จะเป็นชัยชนะ มิฉะนั้น regexp

หรือถ้าคุณมีการควบคุมการสืบค้นและสามารถรับประกันได้ว่าค่าที่คุณพยายามรับจะไม่มีตัวอักษรที่เข้ารหัส URL ใด ๆ (การมีค่าเหล่านี้ในค่าจะเป็นความคิดที่ไม่ดี) - คุณสามารถใช้เวอร์ชันที่ง่ายขึ้นและอ่านง่ายขึ้น ของตัวเลือกที่ 1:

    function getQueryStringValueByName(name) {
        var queryStringFromStartOfValue = location.search.split(name + '=')[1];
         return queryStringFromStartOfValue !== undefined ? queryStringFromStartOfValue.split('&')[0] : null;

7
เรียบร้อยมาก! มันจะไม่ทำงาน แต่ถ้าคุณมีมูลค่าที่ก่อนหน้านี้มีชื่อที่สำคัญที่สิ้นสุดกับคนที่คุณต้องการเช่นบนget('value') http://the-url?oldvalue=1&value=2
รูปี

3
อย่างไรก็ตามหากคุณรู้ว่าชื่อพารามิเตอร์กำลังรออยู่นี่จะเป็นวิธีที่เร็วกว่า
Martin Borthiry

แก้ไข: หากคุณเพียงแค่ทดสอบที่halfเป็น truthy ?param=ผลตอบแทนนี้เป็นโมฆะสำหรับพารามิเตอร์ที่ว่างเปล่าเช่น มันควรจะคืนค่าสตริงว่างในกรณีนี้และตรวจสอบการhalf !== undefinedแก้ไขนั้น
philh

เย็น! ฉันทำสายการบินfunction get(param){return decodeURIComponent((location.search.split(param+'=')[1]||'').split('&')[0])}
niutech

ฉันต้องเปลี่ยนบรรทัดที่สองเพื่อreturn half !== undefined ? decodeURIComponent(half[1].split('&')[0]) : null;ให้มันทำงาน
divillysausages

95

นี่คือการแทงของฉันที่จะทำให้ทางออกที่ยอดเยี่ยมของ Andy E เป็นปลั๊กอิน jQuery ที่สมบูรณ์

;(function ($) {
    $.extend({      
        getQueryString: function (name) {           
            function parseParams() {
                var params = {},
                    e,
                    a = /\+/g,  // Regex for replacing addition symbol with a space
                    r = /([^&=]+)=?([^&]*)/g,
                    d = function (s) { return decodeURIComponent(s.replace(a, " ")); },
                    q = window.location.search.substring(1);

                while (e = r.exec(q))
                    params[d(e[1])] = d(e[2]);

                return params;
            }

            if (!this.queryStringParams)
                this.queryStringParams = parseParams(); 

            return this.queryStringParams[name];
        }
    });
})(jQuery);

ไวยากรณ์คือ:

var someVar = $.getQueryString('myParam');

สุดยอดของทั้งสองโลก!


76

หากคุณทำการปรับเปลี่ยน URL มากกว่าการแยกวิเคราะห์สตริงการสืบค้นคุณอาจพบว่าURI.js มีประโยชน์ มันเป็นห้องสมุดสำหรับจัดการ URL - และมาพร้อมกับเสียงระฆังและเสียงนกหวีดทั้งหมด (ขออภัยสำหรับการโฆษณาด้วยตนเองที่นี่)

เพื่อแปลงการสอบถามของคุณเป็นแผนที่:

var data = URI('?foo=bar&bar=baz&foo=world').query(true);
data == {
  "foo": ["bar", "world"],
  "bar": "baz"
}

(URI.js ยัง "แก้ไข" querystrings เลว ๆ ชอบ?&foo&&bar=baz&ไป?foo&bar=baz)


// ต้องโหลด src / URI.fragmentURI.js
JoeB

1
+1 URI.js เป็นปลั๊กอินเล็ก ๆ ที่ยอดเยี่ยม คุณสามารถทำvar data = URI.parseQuery('?foo=bar&bar=baz&foo=world');เพื่อผลลัพธ์เดียวกัน ( เอกสาร )
Yarin

62

ผมชอบวิธีการแก้ปัญหาของไรอันเฟลาน แต่ฉันไม่เห็นว่าจะขยาย jQuery ในจุดใด ไม่มีการใช้งานฟังก์ชั่น jQuery

ในทางกลับกันฉันชอบฟังก์ชั่นในตัวใน Google Chrome: window.location.getParameter

เหตุใดจึงไม่ใช้สิ่งนี้ ตกลงเบราว์เซอร์อื่น ๆ ไม่มี ลองสร้างฟังก์ชั่นนี้ถ้ามันไม่มีอยู่:

if (!window.location.getParameter ) {
  window.location.getParameter = function(key) {
    function parseParams() {
        var params = {},
            e,
            a = /\+/g,  // Regex for replacing addition symbol with a space
            r = /([^&=]+)=?([^&]*)/g,
            d = function (s) { return decodeURIComponent(s.replace(a, " ")); },
            q = window.location.search.substring(1);

        while (e = r.exec(q))
            params[d(e[1])] = d(e[2]);

        return params;
    }

    if (!this.queryStringParams)
        this.queryStringParams = parseParams(); 

    return this.queryStringParams[key];
  };
}

ฟังก์ชั่นนี้มากหรือน้อยจาก Ryan Phelan แต่มันถูกห่อหุ้มแตกต่างกันไป: ชื่อที่ชัดเจนและไม่มีการพึ่งพาไลบรารี javascript อื่น ๆ เพิ่มเติมเกี่ยวกับฟังก์ชั่นนี้ในบล็อกของฉัน


3
ดูเหมือน window.location.getParameter () ได้ถูกลบออกจาก Chrome
mhenry1384

54

นี่เป็นวิธีที่รวดเร็วในการรับวัตถุคล้ายกับอาร์เรย์PHP $ _GET :

function get_query(){
    var url = location.search;
    var qs = url.substring(url.indexOf('?') + 1).split('&');
    for(var i = 0, result = {}; i < qs.length; i++){
        qs[i] = qs[i].split('=');
        result[qs[i][0]] = decodeURIComponent(qs[i][1]);
    }
    return result;
}

การใช้งาน:

var $_GET = get_query();

สำหรับสตริงแบบสอบถามx=5&y&z=hello&x=6จะส่งคืนวัตถุ:

{
  x: "6",
  y: undefined,
  z: "hello"
}

หากคุณต้องการเป็นปลั๊กอิน jQuery นี่คือ: (function($) { $.extend({ get_query: function (name) { var url = location.href; var qs = url.substring(url.indexOf('?') + 1).split('&'); for(var i = 0, result = {}; i < qs.length; i++){ qs[i] = qs[i].split('='); result[qs[i][0]] = qs[i][1]; } return result; } }); })(jQuery);และใช้เช่นนี้:$.get_query()
ทิม

ขอบคุณ ฉันก็ลงเอยด้วยการใช้สิ่งนี้ ฉันเพิ่มสิ่งนี้ก่อนข้อความสั่งคืนของคุณ: ถ้า (param) ส่งคืนผลลัพธ์ [param] ด้วยวิธีนี้ฉันยังสามารถรับ get_query ('foo') ได้ถ้าต้องการ
sqram

1
ไม่ทำงานหากคุณมีแฮช ตัวอย่างเช่น: ? Test.aspx จะกลับมา {ทดสอบ "t1 # เริ่มต้น"} และผมคาดว่า {ทดสอบ "T1"}
Bogdan เอ็ม

@BogdanM: แน่นอน จะต้องถูกแทนที่ด้วยlocation.href location.search
แดนดาสคเลสุ

53

ทำให้มันง่ายในรหัส JavaScript ธรรมดา:

function qs(key) {
    var vars = [], hash;
    var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
    for(var i = 0; i < hashes.length; i++)
    {
        hash = hashes[i].split('=');
        vars.push(hash[0]);
        vars[hash[0]] = hash[1];
    }
    return vars[key];
}

โทรจากที่ใดก็ได้ในรหัส JavaScript:

var result = qs('someKey');

1
ฉันคิดว่าคุณกำลังทำสิ่งที่คล้ายกับผม แต่ผมคิดว่าวิธีการของฉันเป็นมาก simplier stackoverflow.com/a/21152762/985454
Qwerty

ผมขอแนะนำให้คุณรู้จักกับ (กลองโปรด) window.location.search!
ErikE

46

ทั้งหมดนี้เป็นคำตอบที่ยอดเยี่ยม แต่ฉันต้องการบางสิ่งที่แข็งแกร่งกว่านี้เล็กน้อยและคิดว่าคุณทุกคนอาจต้องการมีสิ่งที่ฉันสร้างขึ้น

มันเป็นวิธีการห้องสมุดง่าย ๆ ที่จะแยกและการจัดการของพารามิเตอร์ URL วิธีการแบบสแตติกมีวิธีการย่อยต่อไปนี้ที่สามารถเรียกบน URL หัวเรื่อง:

  • gethost
  • getPath
  • getHash
  • setHash
  • getParams
  • getQuery
  • setParam
  • getParam
  • hasParam
  • removeParam

ตัวอย่าง:

URLParser(url).getParam('myparam1')

var url = "http://www.test.com/folder/mypage.html?myparam1=1&myparam2=2#something";

function URLParser(u){
    var path="",query="",hash="",params;
    if(u.indexOf("#") > 0){
        hash = u.substr(u.indexOf("#") + 1);
        u = u.substr(0 , u.indexOf("#"));
    }
    if(u.indexOf("?") > 0){
        path = u.substr(0 , u.indexOf("?"));
        query = u.substr(u.indexOf("?") + 1);
        params= query.split('&');
    }else
        path = u;
    return {
        getHost: function(){
            var hostexp = /\/\/([\w.-]*)/;
            var match = hostexp.exec(path);
            if (match != null && match.length > 1)
                return match[1];
            return "";
        },
        getPath: function(){
            var pathexp = /\/\/[\w.-]*(?:\/([^?]*))/;
            var match = pathexp.exec(path);
            if (match != null && match.length > 1)
                return match[1];
            return "";
        },
        getHash: function(){
            return hash;
        },
        getParams: function(){
            return params
        },
        getQuery: function(){
            return query;
        },
        setHash: function(value){
            if(query.length > 0)
                query = "?" + query;
            if(value.length > 0)
                query = query + "#" + value;
            return path + query;
        },
        setParam: function(name, value){
            if(!params){
                params= new Array();
            }
            params.push(name + '=' + value);
            for (var i = 0; i < params.length; i++) {
                if(query.length > 0)
                    query += "&";
                query += params[i];
            }
            if(query.length > 0)
                query = "?" + query;
            if(hash.length > 0)
                query = query + "#" + hash;
            return path + query;
        },
        getParam: function(name){
            if(params){
                for (var i = 0; i < params.length; i++) {
                    var pair = params[i].split('=');
                    if (decodeURIComponent(pair[0]) == name)
                        return decodeURIComponent(pair[1]);
                }
            }
            console.log('Query variable %s not found', name);
        },
        hasParam: function(name){
            if(params){
                for (var i = 0; i < params.length; i++) {
                    var pair = params[i].split('=');
                    if (decodeURIComponent(pair[0]) == name)
                        return true;
                }
            }
            console.log('Query variable %s not found', name);
        },
        removeParam: function(name){
            query = "";
            if(params){
                var newparams = new Array();
                for (var i = 0;i < params.length;i++) {
                    var pair = params[i].split('=');
                    if (decodeURIComponent(pair[0]) != name)
                          newparams .push(params[i]);
                }
                params = newparams;
                for (var i = 0; i < params.length; i++) {
                    if(query.length > 0)
                        query += "&";
                    query += params[i];
                }
            }
            if(query.length > 0)
                query = "?" + query;
            if(hash.length > 0)
                query = query + "#" + hash;
            return path + query;
        },
    }
}


document.write("Host: " + URLParser(url).getHost() + '<br>');
document.write("Path: " + URLParser(url).getPath() + '<br>');
document.write("Query: " + URLParser(url).getQuery() + '<br>');
document.write("Hash: " + URLParser(url).getHash() + '<br>');
document.write("Params Array: " + URLParser(url).getParams() + '<br>');
document.write("Param: " + URLParser(url).getParam('myparam1') + '<br>');
document.write("Has Param: " + URLParser(url).hasParam('myparam1') + '<br>');

document.write(url + '<br>');

// Remove the first parameter
url = URLParser(url).removeParam('myparam1');
document.write(url + ' - Remove the first parameter<br>');

// Add a third parameter
url = URLParser(url).setParam('myparam3',3);
document.write(url + ' - Add a third parameter<br>');

// Remove the second parameter
url = URLParser(url).removeParam('myparam2');
document.write(url + ' - Remove the second parameter<br>');

// Add a hash
url = URLParser(url).setHash('newhash');
document.write(url + ' - Set Hash<br>');

// Remove the last parameter
url = URLParser(url).removeParam('myparam3');
document.write(url + ' - Remove the last parameter<br>');

// Remove a parameter that doesn't exist
url = URLParser(url).removeParam('myparam3');
document.write(url + ' - Remove a parameter that doesn\"t exist<br>');

44

จากMDN :

function loadPageVar (sVar) {
  return unescape(window.location.search.replace(new RegExp("^(?:.*[&\\?]" + escape(sVar).replace(/[\.\+\*]/g, "\\$&") + "(?:\\=([^&]*))?)?.*$", "i"), "$1"));
}

alert(loadPageVar("name"));

39

รหัสกอล์ฟ:

var a = location.search&&location.search.substr(1).replace(/\+/gi," ").split("&");
for (var i in a) {
    var s = a[i].split("=");
    a[i]  = a[unescape(s[0])] = unescape(s[1]);
}

แสดงมัน!

for (i in a) {
    document.write(i + ":" + a[i] + "<br/>");   
};

บน Mac ของฉัน: test.htm?i=can&has=cheezburgerแสดงผล

0:can
1:cheezburger
i:can
has:cheezburger

9
ฉันรักคำตอบของคุณโดยเฉพาะอย่างยิ่งความกระชับของสคริปต์ แต่คุณควรใช้ decodeURIComponent ดูxkr.us/articles/javascript/encode-compareและstackoverflow.com/questions/619323/…
pluckyglen

39

ฉันใช้นิพจน์ทั่วไปบ่อยๆ แต่ไม่ใช่สำหรับสิ่งนั้น

ดูเหมือนว่าฉันจะอ่านสตริงแบบสอบถามได้ง่ายขึ้นและมีประสิทธิภาพยิ่งขึ้นในแอปพลิเคชันของฉันและสร้างวัตถุจากคู่คีย์ / ค่าทั้งหมดเช่น:

var search = function() {
  var s = window.location.search.substr(1),
    p = s.split(/\&/), l = p.length, kv, r = {};
  if (l === 0) {return false;}
  while (l--) {
    kv = p[l].split(/\=/);
    r[kv[0]] = decodeURIComponent(kv[1] || '') || true;
  }
  return r;
}();

สำหรับ URL ที่เหมือนhttp://domain.com?param1=val1&param2=val2คุณจะได้รับค่าของพวกเขาในภายหลังในรหัสของคุณเป็นและsearch.param1search.param2


38
function GET() {
        var data = [];
        for(x = 0; x < arguments.length; ++x)
            data.push(location.href.match(new RegExp("/\?".concat(arguments[x],"=","([^\n&]*)")))[1])
                return data;
    }


example:
data = GET("id","name","foo");
query string : ?id=3&name=jet&foo=b
returns:
    data[0] // 3
    data[1] // jet
    data[2] // b
or
    alert(GET("id")[0]) // return 3

5
นี่เป็นวิธีที่น่าสนใจโดยส่งคืนอาร์เรย์ที่มีค่าจากพารามิเตอร์ที่ระบุ มีปัญหาอย่างน้อยหนึ่งข้อ - URL ไม่ถูกต้องถอดรหัสค่าและจะต้องเข้ารหัส URL ชื่อพารามิเตอร์ที่ใช้ในการจับคู่ด้วย มันจะทำงานกับสตริงการสืบค้นอย่างง่ายในรูปแบบปัจจุบันแม้ว่า psอย่าลืมใช้คำสำคัญ var เมื่อประกาศตัวแปรในสำหรับคำสั่ง
Andy E

38

วิธี joshery Roshambo ไม่ได้ดูแลการถอดรหัส URL

http://snipplr.com/view/26662/get-url-parameters-with-jquery--improved/

เพิ่งเพิ่มความสามารถนั้นพร้อมกับเพิ่มในคำสั่ง return

return decodeURIComponent(results[1].replace(/\+/g, " ")) || 0;

ตอนนี้คุณสามารถค้นหาสรุปสาระสำคัญได้ที่:

$.urlParam = function(name){
var results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(window.location.href);
if (!results) { return 0; }
return decodeURIComponent(results[1].replace(/\+/g, " ")) || 0;
}

36

ฉันชอบอันนี้ (นำมาจาก jquery-howto.blogspot.co.uk):

// get an array with all querystring values
// example: var valor = getUrlVars()["valor"];
function getUrlVars() {
    var vars = [], hash;
    var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
    for (var i = 0; i < hashes.length; i++) {
        hash = hashes[i].split('=');
        vars.push(hash[0]);
        vars[hash[0]] = hash[1];
    }
    return vars;
}

ใช้งานได้ดีสำหรับฉัน


36

นี่คือการแก้ไขของฉันสำหรับคำตอบที่ยอดเยี่ยมนี้ - เพิ่มความสามารถในการแยกสตริงการสืบค้นด้วยคีย์ที่ไม่มีค่า

var url = 'http://sb.com/reg/step1?param';
var qs = (function(a) {
    if (a == "") return {};
    var b = {};
    for (var i = 0; i < a.length; ++i) {
        var p=a[i].split('=', 2);
        if (p[1]) p[1] = decodeURIComponent(p[1].replace(/\+/g, " "));
        b[p[0]] = p[1];
    }
    return b;
})((url.split('?'))[1].split('&'));

สิ่งสำคัญ! พารามิเตอร์สำหรับฟังก์ชันนั้นในบรรทัดสุดท้ายนั้นแตกต่างกัน นี่เป็นเพียงตัวอย่างของวิธีที่ URL สามารถส่งผ่านไปยังมันเอง คุณสามารถใช้บรรทัดสุดท้ายจากคำตอบของ Bruno เพื่อแยก URL ปัจจุบัน

ดังนั้นสิ่งที่เปลี่ยนไป? ด้วยhttp://sb.com/reg/step1?param=ผลลัพธ์URL จะเหมือนกัน แต่ด้วยhttp://sb.com/reg/step1?paramวิธีการแก้ปัญหาของurl Bruno ส่งคืนวัตถุโดยไม่มีกุญแจในขณะที่เหมืองคืนวัตถุที่มีคีย์paramและundefinedค่า


34

ฉันต้องการวัตถุจากสตริงแบบสอบถามและฉันเกลียดโค้ดจำนวนมาก มันอาจจะไม่แข็งแกร่งที่สุดในจักรวาล แต่มันเป็นโค้ดเพียงไม่กี่บรรทัด

var q = {};
location.href.split('?')[1].split('&').forEach(function(i){
    q[i.split('=')[0]]=i.split('=')[1];
});

URL ที่ต้องการthis.htm?hello=world&foo=barจะสร้าง:

{hello:'world', foo:'bar'}

4
เรียบร้อย ตาม Mozilla แต่forEachไม่ทำงานบน IE7 หรือ 8 และฉันสงสัยว่ามันจะล้มถ้าไม่มีสตริงข้อความค้นหาเลย การปรับปรุงที่น้อยที่สุดหนึ่งที่จะครอบคลุมกรณีเพิ่มเติมจะเป็นdecodeURIComponentค่าที่คุณเก็บไว้ - และเนื้อหาที่สำคัญเช่นกัน แต่คุณมีโอกาสน้อยที่จะใช้สตริงคี่ในที่
โฟโต้

1
ดีและเรียบง่าย ไม่จัดการกับพารามิเตอร์ของอาร์เรย์หรือ?a&b&cแต่มันสามารถอ่านได้จริง ๆ (และคล้ายกับความคิดแรกของฉัน) นอกจากนี้ยังsplitมีการซ้ำซ้อน แต่ฉันมีปลาประสิทธิภาพที่ใหญ่กว่าที่จะทอดกว่าการแยกสตริงอักขระ 10 ตัวสองครั้ง
cod3monk3y

1
เมื่อ querystring คือ "? hello = world & one = a = b & two = 2" จากนั้นเมื่อคุณคว้าค่าของ 'one' คุณจะได้รับส่วนก่อน '=' แรกในค่า ค่าของมันจะเป็น 'a = b' แต่คุณจะได้รับ 'a' เพียงเพราะคุณแยก 'one = a = b' บน '=' นี่เป็นรถบั๊กกี้ : ((
Shawn Kovac

2
ฉันจะใช้location.search.substr(1)แทนlocation.href.split('?')[1]การหลีกเลี่ยงการแฮช ( #anchor) พร้อมกับพารามิเตอร์การสืบค้นล่าสุด
mlt

ใช่ให้ฉันแนะนำคุณด้วยlocation.search!
ErikE

32

ต่อไปนี้เป็นเวอร์ชั่นขยายของ Andy E ที่เชื่อมโยง "จัดการสตริงการสืบค้นสไตล์อาเรย์" - รุ่น แก้ไขข้อบกพร่อง ( ?key=1&key[]=2&key[]=3; 1สูญหายและแทนที่ด้วย[2,3]) ทำการปรับปรุงประสิทธิภาพเล็กน้อย (การถอดรหัสค่าใหม่การคำนวณตำแหน่ง "[" ฯลฯ ) และเพิ่มการปรับปรุงจำนวนหนึ่ง (เพิ่มการทำงานการ?key=1&key=2สนับสนุนสำหรับ;ตัวคั่น) . ฉันทิ้งตัวแปรที่น่ารำคาญสั้น ๆ แต่เพิ่มความคิดเห็นมากมายเพื่อให้สามารถอ่านได้ (โอ้และฉันนำกลับมาใช้ใหม่vภายในฟังก์ชั่นในท้องถิ่นขออภัยถ้ามันสับสน;)

มันจะจัดการกับการสอบถามต่อไปนี้ ...

? การทดสอบ = สวัสดีและคน = Neek และคน [] = เจฟฟ์และคน [] = จิมและคน [พิเศษ] = John & test3 และ nocache = 1398914891264

... ทำให้เป็นวัตถุที่ดูเหมือน ...

{
    "test": "Hello",
    "person": {
        "0": "neek",
        "1": "jeff",
        "2": "jim",
        "length": 3,
        "extra": "john"
    },
    "test3": "",
    "nocache": "1398914891264"
}

ดังที่คุณเห็นด้านบนเวอร์ชันนี้จัดการกับบางส่วนของอาร์เรย์ "malformed" เช่น - person=neek&person[]=jeff&person[]=jimหรือperson=neek&person=jeff&person=jimเป็นคีย์ที่สามารถระบุตัวตนและใช้งานได้ (อย่างน้อยในชื่อของDotValueCollection.Add ) ของ dotNet :

หากคีย์ที่ระบุมีอยู่แล้วในอินสแตนซ์ NameValueCollection เป้าหมายค่าที่ระบุจะถูกเพิ่มไปยังรายการค่าที่คั่นด้วยเครื่องหมายจุลภาคที่มีอยู่ในรูปแบบ "value1, value2, value3"

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

รหัส:

getQueryStringKey = function(key) {
    return getQueryStringAsObject()[key];
};


getQueryStringAsObject = function() {
    var b, cv, e, k, ma, sk, v, r = {},
        d = function (v) { return decodeURIComponent(v).replace(/\+/g, " "); }, //# d(ecode) the v(alue)
        q = window.location.search.substring(1), //# suggested: q = decodeURIComponent(window.location.search.substring(1)),
        s = /([^&;=]+)=?([^&;]*)/g //# original regex that does not allow for ; as a delimiter:   /([^&=]+)=?([^&]*)/g
    ;

    //# ma(make array) out of the v(alue)
    ma = function(v) {
        //# If the passed v(alue) hasn't been setup as an object
        if (typeof v != "object") {
            //# Grab the cv(current value) then setup the v(alue) as an object
            cv = v;
            v = {};
            v.length = 0;

            //# If there was a cv(current value), .push it into the new v(alue)'s array
            //#     NOTE: This may or may not be 100% logical to do... but it's better than loosing the original value
            if (cv) { Array.prototype.push.call(v, cv); }
        }
        return v;
    };

    //# While we still have key-value e(ntries) from the q(uerystring) via the s(earch regex)...
    while (e = s.exec(q)) { //# while((e = s.exec(q)) !== null) {
        //# Collect the open b(racket) location (if any) then set the d(ecoded) v(alue) from the above split key-value e(ntry) 
        b = e[1].indexOf("[");
        v = d(e[2]);

        //# As long as this is NOT a hash[]-style key-value e(ntry)
        if (b < 0) { //# b == "-1"
            //# d(ecode) the simple k(ey)
            k = d(e[1]);

            //# If the k(ey) already exists
            if (r[k]) {
                //# ma(make array) out of the k(ey) then .push the v(alue) into the k(ey)'s array in the r(eturn value)
                r[k] = ma(r[k]);
                Array.prototype.push.call(r[k], v);
            }
            //# Else this is a new k(ey), so just add the k(ey)/v(alue) into the r(eturn value)
            else {
                r[k] = v;
            }
        }
        //# Else we've got ourselves a hash[]-style key-value e(ntry) 
        else {
            //# Collect the d(ecoded) k(ey) and the d(ecoded) sk(sub-key) based on the b(racket) locations
            k = d(e[1].slice(0, b));
            sk = d(e[1].slice(b + 1, e[1].indexOf("]", b)));

            //# ma(make array) out of the k(ey) 
            r[k] = ma(r[k]);

            //# If we have a sk(sub-key), plug the v(alue) into it
            if (sk) { r[k][sk] = v; }
            //# Else .push the v(alue) into the k(ey)'s array
            else { Array.prototype.push.call(r[k], v); }
        }
    }

    //# Return the r(eturn value)
    return r;
};

สำหรับการรับค่าสตริงแบบสอบถามคุณสามารถใช้ฟังก์ชัน "GetParameterValues" นี้ ในที่นี้คุณเพียงแค่ต้องส่งชื่อพารามิเตอร์ของแบบสอบถาม stirng และมันจะคืนค่า $ (document) .ready (function () {var bid = GetParameterValues ​​('token');}); ฟังก์ชัน GetParameterValues ​​(พารามิเตอร์) {var url = decodeURIComponent (window.location.href) url = url.slice (url.indexOf ('?') + 1) .split ('&'); สำหรับ (var i = 0; i <url.length; i ++) {var urlparam = url [i] .split ('='); if (urlparam [0] == param) {return urlparam [1]; }}
Mike Clark

1
ฉันใช้มันมาระยะหนึ่งแล้วและมันก็เยี่ยมมาก ยกเว้นการจัดการอาร์เรย์ urlencoded การใช้q = decodeURIComponent(window.location.search.substring(1)),ช่วยก็ทำได้เช่นกัน
Vladislav Dimitrov

31

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

ฉันใช้รุ่นบีบอัดนี้ ฉันกำลังโพสต์แบบไม่บีบอัดสำหรับประเภทสามเณรเพื่ออธิบายสิ่งที่เกิดขึ้นได้ดียิ่งขึ้น

ฉันแน่ใจว่าสิ่งนี้อาจได้รับการปรับให้เหมาะสมหรือทำแตกต่างกันเพื่อให้ทำงานได้เร็วขึ้น

สนุก.

function getQSP(sName, sURL) {
    var theItmToRtn = "";
    var theSrchStrg = location.search;
    if (sURL) theSrchStrg = sURL;
    var sOrig = theSrchStrg;
    theSrchStrg = theSrchStrg.toUpperCase();
    sName = sName.toUpperCase();
    theSrchStrg = theSrchStrg.replace("?", "&") theSrchStrg = theSrchStrg + "&";
    var theSrchToken = "&" + sName + "=";
    if (theSrchStrg.indexOf(theSrchToken) != -1) {
        var theSrchTokenLth = theSrchToken.length;
        var theSrchTokenLocStart = theSrchStrg.indexOf(theSrchToken) + theSrchTokenLth;
        var theLocOfNextAndSign = theSrchStrg.indexOf("&", theSrchTokenLocStart);
        theItmToRtn = unescape(sOrig.substring(theSrchTokenLocStart, theLocOfNextAndSign));
    }
    return unescape(theItmToRtn);
}

นอกจากนี้ควรเลือกใช้ decodeURI () หรือ decodeURIComponent () แทน unescape () developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
......

27

เราเพิ่งเปิดตัวarg.jsโครงการที่มุ่งแก้ไขปัญหานี้ครั้งแล้วครั้งเล่า โดยทั่วไปแล้วจะยากมาก แต่ตอนนี้คุณสามารถทำได้

var name = Arg.get("name");

หรือรับจำนวนมาก:

var params = Arg.all();

และถ้าคุณสนใจความแตกต่างระหว่าง?query=trueและ#hash=trueจากนั้นคุณสามารถใช้Arg.query()และArg.hash()วิธีการ


คุณช่วยฉัน man .. arg.js เป็นวิธีแก้ปัญหาที่ไม่มีการแก้ปัญหาที่ได้รับค่าจาก # ใน IE 8 .. :( คนใดคนหนึ่งที่กำลังค้นหา IE8 # ได้รับจากการร้องขอนี้เป็นวิธีการแก้ ..
Dilip Rajkumar

27

ปัญหาของคำตอบที่ดีที่สุดสำหรับคำถามนั้นก็คือมันไม่ใช่พารามิเตอร์ที่รองรับหลัง # แต่บางครั้งก็จำเป็นต้องได้รับค่านี้ด้วย

ฉันแก้ไขคำตอบเพื่อให้มันแยกสตริงการสืบค้นเต็มรูปแบบที่มีเครื่องหมายแฮชด้วย:

var getQueryStringData = function(name) {
    var result = null;
    var regexS = "[\\?&#]" + name + "=([^&#]*)";
    var regex = new RegExp(regexS);
    var results = regex.exec('?' + window.location.href.split('?')[1]);
    if (results != null) {
        result = decodeURIComponent(results[1].replace(/\+/g, " "));
    }
    return result;
};

1
น่าสนใจถ้าคุณต้องการ แต่ไม่มีมาตรฐานสำหรับรูปแบบของส่วนแฮช AFAIK ดังนั้นจึงไม่ยุติธรรมที่จะเรียกสิ่งนั้นว่าเป็นจุดอ่อนของคำตอบอื่น
รูปี

2
ใช่ฉันรู้. แต่ในแอพของฉันฉันรวมการนำทางของบุคคลที่สาม js ซึ่งมีพารามิเตอร์บางอย่างหลังจากลงชื่อแฮ
Ph0en1x

ตัวอย่างเช่นในหน้าค้นหาของ Google คำค้นหาจะตามด้วยเครื่องหมายแฮช '#'
etlds

25
function GetQueryStringParams(sParam)
{
    var sPageURL = window.location.search.substring(1);
    var sURLVariables = sPageURL.split('&');

    for (var i = 0; i < sURLVariables.length; i++)
    {
        var sParameterName = sURLVariables[i].split('=');
        if (sParameterName[0] == sParam)
        {
            return sParameterName[1];
        }
    }
}​

และนี่คือวิธีที่คุณสามารถใช้ฟังก์ชันนี้โดยสมมติว่า URL นั้นเป็น

http://dummy.com/?stringtext=jquery&stringword=jquerybyexample

var tech = GetQueryStringParams('stringtext');
var blog = GetQueryStringParams('stringword');

มีการใช้งานวิธีการนี้เล็กน้อยที่นี่แล้ว อย่างน้อยที่สุดคุณต้อง decodeUriComponent () ค่าผลลัพธ์ ?stringtext&stringword=fooนอกจากนี้ยังอาจจะเกเรถ้าคุณไม่ได้ระบุค่าเช่น
รูปี

24

หากคุณใช้ Browserify คุณสามารถใช้urlโมดูลจากNode.js :

var url = require('url');

url.parse('http://example.com/?bob=123', true).query;

// returns { "bob": "123" }

อ่านเพิ่มเติม: URL Node.js v0.12.2 คู่มือ & เอกสาร

แก้ไข:คุณสามารถใช้ส่วนต่อประสานURLซึ่งมีการนำไปใช้อย่างกว้างขวางในเกือบทุกเบราว์เซอร์ใหม่และหากรหัสกำลังทำงานบนเบราว์เซอร์เก่าคุณสามารถใช้polyfill แบบนี้ได้ ต่อไปนี้เป็นตัวอย่างโค้ดเกี่ยวกับวิธีใช้ส่วนต่อประสาน URL เพื่อรับพารามิเตอร์การสืบค้น (หรือที่รู้จักว่าพารามิเตอร์การค้นหา)

const url = new URL('http://example.com/?bob=123');
url.searchParams.get('bob'); 

คุณยังสามารถใช้ URLSearchParams ได้นี่เป็นตัวอย่างจาก MDNที่จะใช้กับ URLSearchParams:

var paramsString = "q=URLUtils.searchParams&topic=api";
var searchParams = new URLSearchParams(paramsString);

//Iterate the search parameters.
for (let p of searchParams) {
  console.log(p);
}

searchParams.has("topic") === true; // true
searchParams.get("topic") === "api"; // true
searchParams.getAll("topic"); // ["api"]
searchParams.get("foo") === null; // true
searchParams.append("topic", "webdev");
searchParams.toString(); // "q=URLUtils.searchParams&topic=api&topic=webdev"
searchParams.set("topic", "More webdev");
searchParams.toString(); // "q=URLUtils.searchParams&topic=More+webdev"
searchParams.delete("topic");
searchParams.toString(); // "q=URLUtils.searchParams"

เอกสารสำหรับurlAPI ของโมดูลอยู่ที่นี่: nodejs.org/api/url.html
andrezsanchez

นี่เป็นสิ่งที่ดีสำหรับการพัฒนา nw.js Browserify ไม่จำเป็นต้องใช้เนื่องจากโมดูลโหนดส่วนใหญ่ทำงานได้เหมือนในหน้าต่าง nw.js ฉันได้ทดสอบโค้ดนี้และใช้งานได้อย่างมีเสน่ห์โดยไม่มีการดัดแปลงใด ๆ
Andrew Grothe

นี่มันยอดเยี่ยมมาก! URLSearchParams ทำงานได้อย่างสมบูรณ์แบบ ขอบคุณมาก!
Baran Emre

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