JavaScriptでクエリ文字列値を取得するにはどうすればよいですか?

2009年05月23日に質問されました。  ·  閲覧回数 4M回  ·  ソース

Subliminal Hash picture
2009年05月23日

jQueryを介して(またはなしで)クエリ文字列値を取得するプラグインなしの方法はあり

もしそうなら、どのように? そうでない場合、そうすることができるプラグインはありますか?

回答

Artem Barger picture
2009年05月23日
8624

更新:2018年9月

シンプルでまともな(しかし完全ではない)ブラウザサポートを備えたURLSearchParamsを使用できます。

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

PS

残念ながら、URLSearchParamsは、文字列キーの値を持つクエリ文字列を適切に解析しません。 locutus / parse_strを試してみてください

console.log(new URLSearchParams('a=b&c=d').toString()); // a=b&c=d
console.log(new URLSearchParams('a=b&c=d').get('a')); // b
console.log(new URLSearchParams('filters[a]=b&filters[c]=d').toString()); // filters%5Ba%5D=b&filters%5Bc%5D=d
console.log(new URLSearchParams('filters[a]=b&filters[c]=d').get('filters')); // null

元の

そのためにjQueryは必要ありません。 純粋なJavaScriptを使用できます。

function getParameterByName(name, 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クエリキーの権限のある位置](https://stackoverflow.com/questions/1746507/authoritative-position-of-duplicate-http-get -クエリキー)。 注:この関数では大文字と小文字が区別されます。 大文字と小文字を区別しないパラメータ名を使用する場合は、[RegExpに 'i'修飾子を追加] [2]

これは、同じ結果をより簡潔に実現するための、新しいURLSearchParams仕様に基づく更新です。 以下の「 URLSearchParams 」というタイトルの回答を参照してください。

Andy E picture
2010年05月21日
1730

ここに掲載されているソリューションのいくつかは非効率的です。 スクリプトがパラメーターにアクセスする必要があるたびに正規表現検索を繰り返す必要はまったくありません。パラメーターを連想配列スタイルのオブジェクトに分割する単一の関数で十分です。 HTML 5 History APIを使用していない場合、これはページの読み込みごとに1回だけ必要です。 ここでの他の提案も、URLを正しくデコードできません。

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

    urlParams = {};
    while (match = search.<a i="10">exec</a>(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ペアの法的な区切り文字です。 ;または&を処理するには、より複雑な正規表現が必要になります。これは、 ;が使用されることはまれであり、両方が使用される可能性はさらに低いため、不要だと思います。利用される。 あなたがサポートする必要がある場合は;の代わりに& 、ちょうど正規表現でそれらを交換。


サーバー側の前処理言語を使用している場合は、ネイティブのJSON関数を使用して手間のかかる作業を行うことをお勧めします。 たとえば、PHPでは次のように書くことができます。
<script>var urlParams = <?php echo <a i="34">json_encode</a>($_GET, JSON_HEX_TAG);?>;</script>

はるかに簡単です!

更新しました

新しい機能は、次のように繰り返されるパラメータを取得することです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]);
        }
    }
})();
BrunoLM picture
2010年10月04日
1296

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('&'));

?topic=123&name=query+stringようなURLの場合、次のようになります。

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

グーグルメソッド

グーグルのコードを引き裂く私は彼らが使用する方法を見つけました: 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ように見えますが、charの位置を使用してキー/値を取得します)。 分割すると、パラメータに値があるかどうかがチェックされ、値がある場合は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));

パフォーマンステスト(正規表現メソッドに対する分割メソッド)jsPerf

準備コード:メソッド宣言

テストコードを分割する

var qs = window.GetQueryString(query);

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

正規表現テストコード

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

Windows Server 2008 R2 / 7x64上のFirefox4.0x86でのテスト

  • 分割方法:144,780±2.17%最速
  • 正規表現法:13,891±0.85%| 90%遅い
James picture
2011年03月02日
666

Artem Bargerの回答の改善版:

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

改善の詳細については、 http

Paul Sweatte picture
2012年08月28日
608

URLSearchParams

Firefox 44以降、Opera 36以降、Edge 17以降、Safari 10.3以降、Chrome 49以降は、 URLSearchParamsAPIをサポートして

IEの安定したバージョンのためにグーグルが提案したURLSearchParamsポリフィルがあります。

これはW3Cによって標準化されていませんが、 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);

次のように、URLオブジェクトの省略形の.searchParamsプロパティを使用してパラメータを取得することもできます。

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) {}反復処理することもできます。

リファレンス実装サンプルページが監査およびテストのために利用可能です。

AlfaTeK picture
2011年03月15日
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'

ただし、2014年11月11日の時点で、Purlは維持されなくなり、作成者は代わりにURI.jsを使用することをお勧めします。 jQueryプラグインは、要素に焦点を当てているという点で異なります。文字列で使用するには、jQueryの有無にかかわらず、 URI直接使用します。 同様のコードはそのように見えるでしょう、ここでより完全なドキュメント:

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'
Qwerty picture
2014年01月16日
244

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)})
複数行:
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
})

このすべてのコードは何ですか...
「ヌル合体」短絡評価ES6 Destructuring割り当て矢印関数テンプレート文字列

例:
"?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"



続きを読む... VanillaJavaScriptソリューションについて。

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]

エンコードされた文字?

2番目または両方の分割に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}ます。 次のように解析関数を起動する前に、クエリ文字列を確認することをお勧めします。

if (location.search) location.search.substr(1).split("&").forEach(...)
brandonjp picture
2010年03月20日
220

snipplr.comのRoshamboには、 jQueryを使用したURLパラメーターの取得で説明されているこれを実現するための簡単なスクリプトがあり改善されました。 彼のスクリプトを使用すると、必要なパラメーターだけを簡単に引き出すこともできます。

要点は次のとおりです。

$.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には、これに関するすばらしいブログ投稿もあります。jQueryを使用して

alex picture
2009年05月23日
166

jQueryを使用している場合は、 jQuery BBQ:Back Button&QueryLibraryなどのライブラリを使用できます。

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

})();​

新しいHTMLHistory API、特にhistory.pushState()history.replaceState()により、URLが変更され、パラメーターとその値のキャッシュが無効になる可能性があります。

このバージョンでは、履歴が変更されるたびにパラメータの内部キャッシュが更新されます。

Martin Borthiry picture
2012年09月04日
100

2つの分割を使用するだけです:

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

私は以前のより完全な答えをすべて読んでいました。 しかし、それが最も簡単で高速な方法だと思います。 このjsPerfベンチマークをチェックインでき

Rupのコメントの問題を解決するには、最初の行を以下の2つに変更して、条件付き分割を追加します。 ただし、絶対精度とは、正規表現よりも遅いことを意味します( 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;
}

したがって、Rupのカウンターケースに遭遇しないことがわかっている場合は、これが優先されます。 それ以外の場合は、正規表現。

または、クエリ文字列を制御でき、取得しようとしている値にURLエンコードされた文字が含まれないことを保証できる場合(これらを値に含めることはお勧めできません)-次の少し簡略化された読みやすいバージョンを使用できます最初のオプションの:

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