URL parametrelerini bir JavaScript nesnesine nasıl dönüştürebilirim?


223

Ben böyle bir dize var:

abc=foo&def=%5Basf%5D&xyz=5

Bunu böyle bir JavaScript nesnesine nasıl dönüştürebilirim?

{
  abc: 'foo',
  def: '[asf]',
  xyz: 5
}


1
Değil: developer.mozilla.org/en-US/docs/Web/API/URLSearchParams/… developer.mozilla.org/en-US/docs/Web/API/URL/… (bir dakika beklememiz gerekecek) tüm tarayıcıların bunu alması için biraz daha uzun süre)
Arthur

Yanıtlar:


336

Düzenle

Bu düzenleme, yorumları temel alarak cevabı geliştirir ve açıklar.

var search = location.search.substring(1);
JSON.parse('{"' + decodeURI(search).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g,'":"') + '"}')

Misal

abc=foo&def=%5Basf%5D&xyz=5Beş adımda ayrıştırın :

  • decodeURI: abc = foo & def = [asf] & xyz = 5
  • Kaçış tırnak işaretleri: tırnak işaretleri olmadığı için aynı
  • Değiştir &: abc=foo","def=[asf]","xyz=5
  • Değiştir =: abc":"foo","def":"[asf]","xyz":"5
  • Kıvırcık ve tırnaklarla süsleyin: {"abc":"foo","def":"[asf]","xyz":"5"}

yasal JSON.

Bir geliştirilmiş çözüm arama dizede fazla karakter için izin verir. URI kod çözme için bir reviver işlevi kullanır:

var search = location.search.substring(1);
JSON.parse('{"' + search.replace(/&/g, '","').replace(/=/g,'":"') + '"}', function(key, value) { return key===""?value:decodeURIComponent(value) })

Misal

search = "abc=foo&def=%5Basf%5D&xyz=5&foo=b%3Dar";

verir

Object {abc: "foo", def: "[asf]", xyz: "5", foo: "b=ar"}

Orijinal cevap

Bir astar:

JSON.parse('{"' + decodeURI("abc=foo&def=%5Basf%5D&xyz=5".replace(/&/g, "\",\"").replace(/=/g,"\":\"")) + '"}')

4
Bunun CoffeeScript'te çalışması için normal ifadedeki '=' işaretinden kaçın. .replace (/ \ = / g, "\": \ "")
airlok

175
Bu tek katmanlı değil ... bir uzay istasyonu.
Ziggy

5
kullanırsanız daha iyiJSON.parse('{"' + decodeURI(location.search.substring(1).replace(/&/g, "\",\"").replace(/=/g, "\":\"")) + '"}')
Daniël Tulp

4
Ayrıştırılacak URL'de eşittir işaret karakteriniz varsa bu başarısız olur. EX: "çerez = dlksdlfj = sodkfjhsdlfj"
jholloman

3
Ayrıca değer içermeyen parametrelerden birine sahip olduğunuzda da çalışmaz.
Sych

113

2020 ES6 / 7/8 ve yaklaşırken

ES6 ve sonrasında, Javascript bu sorun için başarılı bir çözüm oluşturmak için çeşitli yapılar sunar.

Bu, URLSearchParams ve yineleyicilerin kullanımını içerir

let params = new URLSearchParams('abc=foo&def=%5Basf%5D&xyz=5');
params.get("abc"); // "foo"

Kullanım durumunuz bunu nesneye dönüştürmenizi gerektiriyorsa, aşağıdaki işlevi uygulayabilirsiniz:

function paramsToObject(entries) {
  let result = {}
  for(let entry of entries) { // each 'entry' is a [key, value] tupple
    const [key, value] = entry;
    result[key] = value;
  }
  return result;
}

Temel Demo

const urlParams = new URLSearchParams('abc=foo&def=%5Basf%5D&xyz=5');
const entries = urlParams.entries(); //returns an iterator of decoded [key,value] tuples
const params = paramsToObject(entries); //{abc:"foo",def:"[asf]",xyz:"5"}

Object.fromEntries ve spread kullanma

Biz kullanabilir Object.fromEntries değiştirilmesi, (aşama 4 anda hangi) paramsToObjectile Object.fromEntries(entries).

Yinelenecek değer çiftleri, anahtarın adı ve değerin değer olduğu liste adı-değer çiftleridir.

Yana URLParams, bir döner iterable kullanarak nesneyi yayılmış operatörü yerine çağıran .entriesayrıca spec başına girdilerini verecektir:

const urlParams = new URLSearchParams('abc=foo&def=%5Basf%5D&xyz=5');
const params = Object.fromEntries(urlParams); // {abc: "foo", def: "[asf]", xyz: "5"}

Not: Tüm değerler, URLSearchParams spesifikasyonuna göre otomatik olarak dizelerdir

Birden fazla aynı tuş

As @siipe işaret, birden aynı anahtar değerleri içeren dizeleri son kullanılabilir değere zorlandığını edilecektir: foo=first_value&foo=second_valueözünde hale gelecektir: {foo: "second_value"}.

Bu cevaba göre: https://stackoverflow.com/a/1746566/1194694 onunla ne yapacağına karar vermek için spesifikasyon yok ve her çerçeve farklı davranabilir.

Yaygın bir kullanım durumu, aynı iki değeri bir diziye birleştirerek çıktı nesnesini bir araya getirmektir:

{foo: ["first_value", "second_value"]}

Bu, aşağıdaki kodla gerçekleştirilebilir:

const groupParamsByKey = (params) => [...params.entries()].reduce((acc, tuple) => {
 // getting the key and value from each tuple
 const [key, val] = tuple;
 if(acc.hasOwnProperty(key)) {
    // if the current key is already an array, we'll add the value to it
    if(Array.isArray(acc[key])) {
      acc[key] = [...acc[key], val]
    } else {
      // if it's not an array, but contains a value, we'll convert it into an array
      // and add the current value to it
      acc[key] = [acc[key], val];
    }
 } else {
  // plain assignment if no special case is present
  acc[key] = val;
 }

return acc;
}, {});

const params = new URLSearchParams('abc=foo&def=%5Basf%5D&xyz=5&def=dude');
const output = groupParamsByKey(params) // {abc: "foo", def: ["[asf]", "dude"], xyz: 5}

2
Bu çözümü önermiyorum. URLSearchParams mantıksız özelliklere sahiptir ( developer.mozilla.org/en-US/docs/Web/API/… )
Seph Reed

1
Üzgünüm ama mantığın bununla bir ilgisi yok. Bir search stringayrıştırıcı olduğunu iddia edebilir - bir URL ile ilişkilendirilmiş olmasına bakılmaksızın yapmak için tasarlanan şey budur
silicakes 10:19

Object.fromEntriestekrarlanan tuşlar için çalışmaz. Eğer böyle bir şey yapmaya çalışırsak ?foo=bar1&foo=bar2, sadece alırız { foo: 'bar2' }. Örneğin, Node.js istek nesnesi bunu ayrıştırır{ foo: ['bar1', 'bar2'] }
Siipe

Haklısınız, ancak bunun hiçbir özelliği yok ve birçok dil nasıl ayrıştırdıklarına dair görüşlü bir yaklaşım sergiliyor: stackoverflow.com/a/1746566/1194694
silicakes

Bu benim için iyi görünüyor, ama tekrarlayan anahtarın değerlerini almak için bunu kullanabiliriz let temp={};Object.keys(params).map(key=>{temp[key]=urlParams.getAll(key)})
Tirumaleshwar Keregadde

46

ES6 bir astar. Temiz ve basit.

Object.fromEntries(new URLSearchParams(location.search));

Özel durumunuz için şöyle olur:

console.log(
  Object.fromEntries(new URLSearchParams('abc=foo&def=%5Basf%5D&xyz=5'))
);


Bu gotchaların avına düşer. "http://place.com?foo=bar&hello=%40world&showThing"üretir{ hello: "@world", http://place.com?foo: "bar", showThing: "" }
Seph Reed

1
Sorunun önerdiği gibi, URL'nin tamamını değil, "foo = bar & hello =% 40world & showThing" gibi sorgu dizesiyle (location.search'ten) kullanmalısınız.
tavuklar

1
Bu kullanılabilir, ancak dikkatle ?someValue=falseolur{ someValue: "false" }
Simon

Tekrarlanan tuşlar için çalışmaz. Eğer böyle bir şey yapmaya çalışırsak ?foo=bar1&foo=bar2, sadece alırız { foo: 'bar2' }. Node.js istek nesnesi bunu ayrıştırıyor{ foo: ['bar1', 'bar2'] }
Siipe

@SephReed, yorumunuzun kullanılan güncellenmiş sürümle ele alındığına inanıyorumlocation.search
KyleMit

27

Böl &sonra her çifti bölmek, ad / değer çiftlerini almak için =. İşte bir örnek:

var str = "abc=foo&def=%5Basf%5D&xy%5Bz=5"
var obj = str.split("&").reduce(function(prev, curr, i, arr) {
    var p = curr.split("=");
    prev[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
    return prev;
}, {});

Düzenli ifadeler kullanan başka bir yaklaşım:

var obj = {}; 
str.replace(/([^=&]+)=([^&]*)/g, function(m, key, value) {
    obj[decodeURIComponent(key)] = decodeURIComponent(value);
}); 

Bu, John Resig'in "Arama ve Değiştirme" özelliğinden uyarlanmıştır .


tx! solda ayrıca decodeURIComponen (p [0]) eklemelisiniz :)
Alex

İlk örnek boş bir sorgu dizesiyle çalışmaz.
Michał Perłakowski

18

Kısa bir çözüm:

location.search
  .slice(1)
  .split('&')
  .map(p => p.split('='))
  .reduce((obj, pair) => {
    const [key, value] = pair.map(decodeURIComponent);
    return ({ ...obj, [key]: value })
  }, {});

bu dizilerle başarısız olur yani: x = 1 & x = 2
Sh eldeeb

16

Şimdiye kadar bulduğum önerilen çözümler daha karmaşık senaryoları kapsamıyor.

Gibi bir sorgu dizesini dönüştürmek gerekiyordu

https://random.url.com?Target=Offer&Method=findAll&filters%5Bhas_goals_enabled%5D%5BTRUE%5D=1&filters%5Bstatus%5D=active&fields%5B%5D=id&fields%5B%5D=name&fields%5B%5D=default_goal_name

gibi bir nesneye:

{
    "Target": "Offer",
    "Method": "findAll",
    "fields": [
        "id",
        "name",
        "default_goal_name"
    ],
    "filters": {
        "has_goals_enabled": {
            "TRUE": "1"
        },
        "status": "active"
    }
}

VEYA:

https://random.url.com?Target=Report&Method=getStats&fields%5B%5D=Offer.name&fields%5B%5D=Advertiser.company&fields%5B%5D=Stat.clicks&fields%5B%5D=Stat.conversions&fields%5B%5D=Stat.cpa&fields%5B%5D=Stat.payout&fields%5B%5D=Stat.date&fields%5B%5D=Stat.offer_id&fields%5B%5D=Affiliate.company&groups%5B%5D=Stat.offer_id&groups%5B%5D=Stat.date&filters%5BStat.affiliate_id%5D%5Bconditional%5D=EQUAL_TO&filters%5BStat.affiliate_id%5D%5Bvalues%5D=1831&limit=9999

INTO:

{
    "Target": "Report",
    "Method": "getStats",
    "fields": [
        "Offer.name",
        "Advertiser.company",
        "Stat.clicks",
        "Stat.conversions",
        "Stat.cpa",
        "Stat.payout",
        "Stat.date",
        "Stat.offer_id",
        "Affiliate.company"
    ],
    "groups": [
        "Stat.offer_id",
        "Stat.date"
    ],
    "limit": "9999",
    "filters": {
        "Stat.affiliate_id": {
            "conditional": "EQUAL_TO",
            "values": "1831"
        }
    }
}

Birden çok çözümü derlemiş ve gerçekten işe yarayan bir çözüm haline getirdim:

KODU:

var getParamsAsObject = function (query) {

    query = query.substring(query.indexOf('?') + 1);

    var re = /([^&=]+)=?([^&]*)/g;
    var decodeRE = /\+/g;

    var decode = function (str) {
        return decodeURIComponent(str.replace(decodeRE, " "));
    };

    var params = {}, e;
    while (e = re.exec(query)) {
        var k = decode(e[1]), v = decode(e[2]);
        if (k.substring(k.length - 2) === '[]') {
            k = k.substring(0, k.length - 2);
            (params[k] || (params[k] = [])).push(v);
        }
        else params[k] = v;
    }

    var assign = function (obj, keyPath, value) {
        var lastKeyIndex = keyPath.length - 1;
        for (var i = 0; i < lastKeyIndex; ++i) {
            var key = keyPath[i];
            if (!(key in obj))
                obj[key] = {}
            obj = obj[key];
        }
        obj[keyPath[lastKeyIndex]] = value;
    }

    for (var prop in params) {
        var structure = prop.split('[');
        if (structure.length > 1) {
            var levels = [];
            structure.forEach(function (item, i) {
                var key = item.replace(/[?[\]\\ ]/g, '');
                levels.push(key);
            });
            assign(params, levels, params[prop]);
            delete(params[prop]);
        }
    }
    return params;
};

Bu en iyi yanıttır, çünkü karmaşık sorguları gerçekten doğru şekilde işler.
Georgy Ivanov

Bence bu sadece işleri karmaşıklaştırıyor, sadece geçirdim obj=encodeURIComponent(JSON.stringify({what:{ever:','},i:['like']})).
tavuklar

15

Bu basit sürüm, açıkçası bazı hata kontrolü eklemek isteyeceksiniz:

var obj = {};
var pairs = queryString.split('&');
for(i in pairs){
    var split = pairs[i].split('=');
    obj[decodeURIComponent(split[0])] = decodeURIComponent(split[1]);
}

1
% 5B ve% 5D karakterlerini dönüştürmek için dizenin kodunu çözmeyi unuttunuz mu?
jfriend00

@Alex - Güncellenmiş kodu veya orijinali kullandınız mı? Orijinalin bir sorunu ve yazım hatası vardı.
Justin Niessner

Değerleri '=' içerdiğinde parametreleri düzgün işleyemez. Önce değerleri '=' olarak keser.
Greck

JSON.parse('{"' + decodeURIComponent(query.replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g,'":"') + '"}'));benim için çalışıyor
Danil Gaponov

1
işe yaramaz name[]=test1&name[]=test2ve sonuçlanırname[]=test2
Rafee

10

$ .String.deparam en eksiksiz önceden inşa edilmiş bir çözüm buldum (iç içe nesneler yapabilir vb.). Check belgelere .


girişinizi hep iç içe ve daha hafif çözümü konusunda endişe etmeye gerek yoktur bir tefrika sorgu dizesi olacak ise sadece muhtemelen daha iyi olduğunu işaret
mattacular

Tabii ki ... ama zaten yapıldı ve test edildi (Justin, ilk cevapta URI kod çözmeyi unutmayı unutmayın - bunlar başlangıçta göründüğünden çok daha karmaşık hale getirebilecek küçük konulardır).
Daff

9

2019 Tek Astarlı Yaklaşım

Özel durumunuz için:

Object.fromEntries(new URLSearchParams('abc=foo&def=%5Basf%5D&xyz=5'));

Birisinin sorgu parametrelerini bir nesneye ayrıştırmak istediği daha genel bir durum için:

Object.fromEntries(new URLSearchParams(location.search));

Object.fromEntries'i kullanamıyorsanız, bu da işe yarar:

Array.from(new URLSearchParams(window.location.search)).reduce((o, i) => ({ ...o, [i[0]]: i[1] }), {});

Ayrıca[...new URLSearchParams(window.location.search)].reduce((o, i) => ({ ...o, [i[0]]: i[1] }), {});
dman

1
URLSearchParams'ta bunun kırıldığı bazı öğeler var. "http://place.com?foo=bar&hello=%40world&showThingüretir { hello: "@world", http://place.com?foo: "bar", showThing: "" }. str.split("?").pop()
Eklemeyi

7

En son URLSearchParams standardına dayanan başka bir çözüm ( https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams )

function getQueryParamsObject() {
  const searchParams = new URLSearchParams(location.search.slice(1));
  return searchParams
    ? _.fromPairs(Array.from(searchParams.entries()))
    : {};
}

Lütfen bu çözümün

Array.from ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from )

ve basitlik adına lodash'ın _.fromPairs ( https://lodash.com/docs#fromPairs ).

SearchParams.entries () yineleyicisine erişiminiz olduğundan daha uyumlu bir çözüm oluşturmak kolay olmalıdır .


6

Aynı sorunu yaşadım, burada çözümleri denedim, ancak URL parametrelerinde dizilerim olduğu için hiçbiri gerçekten işe yaramadı:

?param[]=5&param[]=8&othr_param=abc&param[]=string

Bu yüzden URI'de param dışında bir dizi yapan kendi JS fonksiyonumu yazdım:

/**
 * Creates an object from URL encoded data
 */
var createObjFromURI = function() {
    var uri = decodeURI(location.search.substr(1));
    var chunks = uri.split('&');
    var params = Object();

    for (var i=0; i < chunks.length ; i++) {
        var chunk = chunks[i].split('=');
        if(chunk[0].search("\\[\\]") !== -1) {
            if( typeof params[chunk[0]] === 'undefined' ) {
                params[chunk[0]] = [chunk[1]];

            } else {
                params[chunk[0]].push(chunk[1]);
            }


        } else {
            params[chunk[0]] = chunk[1];
        }
    }

    return params;
}

2
Bu gerçekten yardımcı oldu ve neredeyse tam olarak ne istediğini yaptı. URL parametreleri gibi ise, "[]" nesnede inceliğini tutmak hoşuma gitmedi: bacon [] = yumurta ve pastırma [] = tost. Sonra bir çizgide ilave Yani if(chunk[0].search("\\[\\]") !== -1) {yanichunk[0]=chunk[0].replace(/\[\]$/,'');
rgbflawed

@rgbflawed gelecekteki okuyucu ve okunabilirlik uğruna cevabı düzenlemelisiniz
Webwoman

Birisi yapabilir ve sonra kodu berbat çünkü constyerine kullanın . kullanırsanız çalışan biri hata yapar sabit değişkene değer atayamaz. varcreateObjFromURI = 'some text'constcreateObjFromURI = 'some text'
Justin Liu

5

ES6, URL API ve URLSearchParams API kullanma.

function objectifyQueryString(url) {
  let _url = new URL(url);
  let _params = new URLSearchParams(_url.search);
  let query = Array.from(_params.keys()).reduce((sum, value)=>{
    return Object.assign({[value]: _params.get(value)}, sum);
  }, {});
  return query;
}

5

ES6 bir astar (uzun çizgiyi görerek bu şekilde diyebilirsek)

[...new URLSearchParams(location.search).entries()].reduce((prev, [key,val]) => {prev[key] = val; return prev}, {})


2
Ayrıca, curdaha fazla netlik için yapılandırabilirsiniz. .reduce((prev, [key, val]) => {prev[key] = val})
Allan Lei

önerinizi beğendim Allan Lei. Cevabımı
güncelliyorum

3

Kullanarak oldukça kolay URLSearchParamsJavaScript Web API'sını ,

var paramsString = "q=forum&topic=api";

//returns an iterator object
var searchParams = new URLSearchParams(paramsString);

//Usage
for (let p of searchParams) {
  console.log(p);
}

//Get the query strings
console.log(searchParams.toString());

//You can also pass in objects

var paramsObject = {q:"forum",topic:"api"}

//returns an iterator object
var searchParams = new URLSearchParams(paramsObject);

//Usage
for (let p of searchParams) {
  console.log(p);
}

//Get the query strings
console.log(searchParams.toString());

kullanışlı bağlantılar

NOT : IE'de Desteklenmez



2

Fark ettiğim yerel bir çözüm yok. Dojo'yu tesadüfen kullanırsanız Dojo'da yerleşik bir serileştirme yöntemi vardır.

Aksi takdirde, kendiniz uygulayabilirsiniz:

function unserialize(str) {
  str = decodeURIComponent(str);
  var chunks = str.split('&'),
      obj = {};
  for(var c=0; c < chunks.length; c++) {
    var split = chunks[c].split('=', 2);
    obj[split[0]] = split[1];
  }
  return obj;
}

düzenleme: decodeURIComponent () eklendi


2

Test edilen ve bunu gerçekten kolaylaştıran YouAreI.js adlı hafif bir kütüphane var.

YouAreI = require('YouAreI')
uri = new YouAreI('http://user:pass@www.example.com:3000/a/b/c?d=dad&e=1&f=12.3#fragment');

uri.query_get() => { d: 'dad', e: '1', f: '12.3' }

2

URLSearchParam arayüzünü kullanarak bunu yapmanın en basit yollarından biri.

Çalışma kodu snippet'i aşağıdadır:

let paramObj={},
    querystring=window.location.search,
    searchParams = new URLSearchParams(querystring);    

  //*** :loop to add key and values to the param object.
 searchParams.forEach(function(value, key) {
      paramObj[key] = value;
   });

1

Aynı ismin birden fazla parametresini dikkate aldığı için bu en iyi çözüm gibi görünüyor.

    function paramsToJSON(str) {
        var pairs = str.split('&');
        var result = {};
        pairs.forEach(function(pair) {
            pair = pair.split('=');
            var name = pair[0]
            var value = pair[1]
            if( name.length )
                if (result[name] !== undefined) {
                    if (!result[name].push) {
                        result[name] = [result[name]];
                    }
                    result[name].push(value || '');
                } else {
                    result[name] = value || '';
                }
        });
        return( result );
    }

<a href="index.html?x=1&x=2&x=3&y=blah">something</a>
paramsToJSON("x=1&x=2&x=3&y=blah"); 

console yields => {x: Array[3], y: "blah"} where x is an array as is proper JSON

Daha sonra bir jQuery eklentisine dönüştürmeye karar verdim ...

$.fn.serializeURLParams = function() {
    var result = {};

    if( !this.is("a") || this.attr("href").indexOf("?") == -1 ) 
        return( result );

    var pairs = this.attr("href").split("?")[1].split('&');
    pairs.forEach(function(pair) {
        pair = pair.split('=');
        var name = decodeURI(pair[0])
        var value = decodeURI(pair[1])
        if( name.length )
            if (result[name] !== undefined) {
                if (!result[name].push) {
                    result[name] = [result[name]];
                }
                result[name].push(value || '');
            } else {
                result[name] = value || '';
            }
    });
    return( result )
}

<a href="index.html?x=1&x=2&x=3&y=blah">something</a>
$("a").serializeURLParams(); 

console yields => {x: Array[3], y: "blah"} where x is an array as is proper JSON

Şimdi, ilk sadece parametreleri kabul eder, ancak jQuery eklentisi tüm url'yi alır ve serileştirilmiş parametreleri döndürür.


1

İşte kullandığım:

var params = {};
window.location.search.substring(1).split('&').forEach(function(pair) {
  pair = pair.split('=');
  if (pair[1] !== undefined) {
    var key = decodeURIComponent(pair[0]),
        val = decodeURIComponent(pair[1]),
        val = val ? val.replace(/\++/g,' ').trim() : '';

    if (key.length === 0) {
      return;
    }
    if (params[key] === undefined) {
      params[key] = val;
    }
    else {
      if ("function" !== typeof params[key].push) {
        params[key] = [params[key]];
      }
      params[key].push(val);
    }
  }
});
console.log(params);

Temel kullanım, ör.
?a=aa&b=bb
Object {a: "aa", b: "bb"}

Yinelenen parametreler, ör.
?a=aa&b=bb&c=cc&c=potato
Object {a: "aa", b: "bb", c: ["cc","potato"]}

Eksik anahtarlar, ör.
?a=aa&b=bb&=cc
Object {a: "aa", b: "bb"}

Eksik değerler, örn.
?a=aa&b=bb&c
Object {a: "aa", b: "bb"}

Yukarıdaki JSON / regex çözümleri bu tuhaf URL'ye bir sözdizimi hatası atar:
?a=aa&b=bb&c=&=dd&e
Object {a: "aa", b: "bb", c: ""}


1

İşte benim hızlı ve kirli sürümüm, temelde '&' ile ayrılmış URL parametrelerini dizi öğelerine ayırıyor ve sonra o nesnenin içine '=' ile ayrılmış anahtar / değer çiftlerini ekleyerek tekrar ediyor. Kodlanmış karakterleri normal dize eşdeğerlerine çevirmek için decodeURIComponent () kullanıyorum (% 20 boşluk olur,% 26 '&' vb. Olur):

function deparam(paramStr) {
    let paramArr = paramStr.split('&');     
    let paramObj = {};
    paramArr.forEach(e=>{
        let param = e.split('=');
        paramObj[param[0]] = decodeURIComponent(param[1]);
    });
    return paramObj;
}

misal:

deparam('abc=foo&def=%5Basf%5D&xyz=5')

İadeler

{
    abc: "foo"
    def:"[asf]"
    xyz :"5"
}

Tek sorun xyz bir dize ve bir sayı değil (decodeURIComponent () kullanarak), ama bunun ötesinde onun kötü bir başlangıç ​​noktası değil.


1
//under ES6 
const getUrlParamAsObject = (url = window.location.href) => {
    let searchParams = url.split('?')[1];
    const result = {};
    //in case the queryString is empty
    if (searchParams!==undefined) {
        const paramParts = searchParams.split('&');
        for(let part of paramParts) {
            let paramValuePair = part.split('=');
            //exclude the case when the param has no value
            if(paramValuePair.length===2) {
                result[paramValuePair[0]] = decodeURIComponent(paramValuePair[1]);
            }
        }

    }
    return result;
}

Bu regex tabanlı cevapların bazılarına kıyasla (2017'de) bu yöntemi gerçekten seviyorum. Çok işlevli ok işlevini doldurun (veya geleneksel bir işlev olarak yeniden yazın), bunun oldukça çapraz tarayıcıda iyi çalışması gerektiğini düşünüyorum
Scribblemacher

@Scribblemacher with Babel'in yardımı ile bunu diğer ortamlarda iyi yapabilirsiniz
XYz Amos

1

Phpjs kullanma

function parse_str(str, array) {
  //       discuss at: http://phpjs.org/functions/parse_str/
  //      original by: Cagri Ekin
  //      improved by: Michael White (http://getsprink.com)
  //      improved by: Jack
  //      improved by: Brett Zamir (http://brett-zamir.me)
  //      bugfixed by: Onno Marsman
  //      bugfixed by: Brett Zamir (http://brett-zamir.me)
  //      bugfixed by: stag019
  //      bugfixed by: Brett Zamir (http://brett-zamir.me)
  //      bugfixed by: MIO_KODUKI (http://mio-koduki.blogspot.com/)
  // reimplemented by: stag019
  //         input by: Dreamer
  //         input by: Zaide (http://zaidesthings.com/)
  //         input by: David Pesta (http://davidpesta.com/)
  //         input by: jeicquest
  //             note: When no argument is specified, will put variables in global scope.
  //             note: When a particular argument has been passed, and the returned value is different parse_str of PHP. For example, a=b=c&d====c
  //             test: skip
  //        example 1: var arr = {};
  //        example 1: parse_str('first=foo&second=bar', arr);
  //        example 1: $result = arr
  //        returns 1: { first: 'foo', second: 'bar' }
  //        example 2: var arr = {};
  //        example 2: parse_str('str_a=Jack+and+Jill+didn%27t+see+the+well.', arr);
  //        example 2: $result = arr
  //        returns 2: { str_a: "Jack and Jill didn't see the well." }
  //        example 3: var abc = {3:'a'};
  //        example 3: parse_str('abc[a][b]["c"]=def&abc[q]=t+5');
  //        returns 3: {"3":"a","a":{"b":{"c":"def"}},"q":"t 5"}

  var strArr = String(str)
    .replace(/^&/, '')
    .replace(/&$/, '')
    .split('&'),
    sal = strArr.length,
    i, j, ct, p, lastObj, obj, lastIter, undef, chr, tmp, key, value,
    postLeftBracketPos, keys, keysLen,
    fixStr = function(str) {
      return decodeURIComponent(str.replace(/\+/g, '%20'));
    };

  if (!array) {
    array = this.window;
  }

  for (i = 0; i < sal; i++) {
    tmp = strArr[i].split('=');
    key = fixStr(tmp[0]);
    value = (tmp.length < 2) ? '' : fixStr(tmp[1]);

    while (key.charAt(0) === ' ') {
      key = key.slice(1);
    }
    if (key.indexOf('\x00') > -1) {
      key = key.slice(0, key.indexOf('\x00'));
    }
    if (key && key.charAt(0) !== '[') {
      keys = [];
      postLeftBracketPos = 0;
      for (j = 0; j < key.length; j++) {
        if (key.charAt(j) === '[' && !postLeftBracketPos) {
          postLeftBracketPos = j + 1;
        } else if (key.charAt(j) === ']') {
          if (postLeftBracketPos) {
            if (!keys.length) {
              keys.push(key.slice(0, postLeftBracketPos - 1));
            }
            keys.push(key.substr(postLeftBracketPos, j - postLeftBracketPos));
            postLeftBracketPos = 0;
            if (key.charAt(j + 1) !== '[') {
              break;
            }
          }
        }
      }
      if (!keys.length) {
        keys = [key];
      }
      for (j = 0; j < keys[0].length; j++) {
        chr = keys[0].charAt(j);
        if (chr === ' ' || chr === '.' || chr === '[') {
          keys[0] = keys[0].substr(0, j) + '_' + keys[0].substr(j + 1);
        }
        if (chr === '[') {
          break;
        }
      }

      obj = array;
      for (j = 0, keysLen = keys.length; j < keysLen; j++) {
        key = keys[j].replace(/^['"]/, '')
          .replace(/['"]$/, '');
        lastIter = j !== keys.length - 1;
        lastObj = obj;
        if ((key !== '' && key !== ' ') || j === 0) {
          if (obj[key] === undef) {
            obj[key] = {};
          }
          obj = obj[key];
        } else { // To insert new dimension
          ct = -1;
          for (p in obj) {
            if (obj.hasOwnProperty(p)) {
              if (+p > ct && p.match(/^\d+$/g)) {
                ct = +p;
              }
            }
          }
          key = ct + 1;
        }
      }
      lastObj[key] = value;
    }
  }
}

1

Mike Causer'ın cevabının üzerine inşa etmek, aynı anahtar ( foo=bar&foo=baz) ve ayrıca virgülle ayrılmış parametreler ( foo=bar,baz,bin) ile birden fazla parametre dikkate alan bu işlevi yaptım . Ayrıca belirli bir sorgu anahtarını aramanızı sağlar.

function getQueryParams(queryKey) {
    var queryString = window.location.search;
    var query = {};
    var pairs = (queryString[0] === '?' ? queryString.substr(1) : queryString).split('&');
    for (var i = 0; i < pairs.length; i++) {
        var pair = pairs[i].split('=');
        var key = decodeURIComponent(pair[0]);
        var value = decodeURIComponent(pair[1] || '');
        // Se possui uma vírgula no valor, converter em um array
        value = (value.indexOf(',') === -1 ? value : value.split(','));

        // Se a key já existe, tratar ela como um array
        if (query[key]) {
            if (query[key].constructor === Array) {
                // Array.concat() faz merge se o valor inserido for um array
                query[key] = query[key].concat(value);
            } else {
                // Se não for um array, criar um array contendo o valor anterior e o novo valor
                query[key] = [query[key], value];
            }
        } else {
            query[key] = value;
        }
    }

    if (typeof queryKey === 'undefined') {
        return query;
    } else {
        return query[queryKey];
    }
}

Örnek girdi: foo.html?foo=bar&foo=baz&foo=bez,boz,buz&bar=1,2,3

Örnek çıktı

{
    foo: ["bar","baz","bez","boz","buz"],
    bar: ["1","2","3"]
}


1

console.log(decodeURI('abc=foo&def=%5Basf%5D&xyz=5')
  .split('&')
  .reduce((result, current) => {
    const [key, value] = current.split('=');

    result[key] = value;

    return result
  }, {}))


0

İLK U VAR ​​NEDİR TANIMLAMAK GEREKİR:

function getVar()
{
    this.length = 0;
    this.keys = [];
    this.push = function(key, value)
    {
        if(key=="") key = this.length++;
        this[key] = value;
        this.keys.push(key);
        return this[key];
    }
}

Sadece okumaktan:

function urlElement()
{
    var thisPrototype = window.location;
    for(var prototypeI in thisPrototype) this[prototypeI] = thisPrototype[prototypeI];
    this.Variables = new getVar();
    if(!this.search) return this;
    var variables = this.search.replace(/\?/g,'').split('&');
    for(var varI=0; varI<variables.length; varI++)
    {
        var nameval = variables[varI].split('=');
        var name = nameval[0].replace(/\]/g,'').split('[');
        var pVariable = this.Variables;
        for(var nameI=0;nameI<name.length;nameI++)
        {
            if(name.length-1==nameI) pVariable.push(name[nameI],nameval[1]);
            else var pVariable = (typeof pVariable[name[nameI]] != 'object')? pVariable.push(name[nameI],new getVar()) : pVariable[name[nameI]];
        }
    }
}

ve aşağıdaki gibi kullanın:

var mlocation = new urlElement();
mlocation = mlocation.Variables;
for(var key=0;key<mlocation.keys.length;key++)
{
    console.log(key);
    console.log(mlocation[mlocation.keys[key]];
}

Lütfen cevaplarınızı birleştirin. Diğerini düzenleyin , ardından bunu silin.
Bergi

0

Ayrıca +URL ( decodeURIComponent yok ) sorgu bölümünde uğraşmak gerekiyordu , bu yüzden Wolfgang'ın kodu olmak için uyarlanmış:

var search = location.search.substring(1);
search = search?JSON.parse('{"' + search.replace(/\+/g, ' ').replace(/&/g, '","').replace(/=/g,'":"') + '"}',
             function(key, value) { return key===""?value:decodeURIComponent(value)}):{};

Benim durumumda, URL'ye hazır form parametrelerini almak için jQuery kullanıyorum, daha sonra bu nesneyi bir nesne oluşturmak için kullanıyorum ve daha sonra kolayca nesne üzerindeki parametreleri güncelleyebilir ve sorgu URL'sini yeniden oluşturabiliriz, örneğin:

var objForm = JSON.parse('{"' + $myForm.serialize().replace(/\+/g, ' ').replace(/&/g, '","').replace(/=/g,'":"') + '"}',
             function(key, value) { return key===""?value:decodeURIComponent(value)});
objForm.anyParam += stringToAddToTheParam;
var serializedForm = $.param(objForm);

0

Bu şekilde yaparım:

const uri = new URL('https://example.org/?myvar1=longValue&myvar2=value')
const result = {}
for (let p of uri.searchParams) {
  result[p[0]] = p[1]
}

0

Özyinelemeye ihtiyacınız varsa, küçük js-uzantı-ling kütüphanesini kullanabilirsiniz.

npm i js-extension-ling
const jsx = require("js-extension-ling");

console.log(jsx.queryStringToObject("a=1")); 
console.log(jsx.queryStringToObject("a=1&a=3")); 
console.log(jsx.queryStringToObject("a[]=1")); 
console.log(jsx.queryStringToObject("a[]=1&a[]=pomme")); 
console.log(jsx.queryStringToObject("a[0]=one&a[1]=five"));
console.log(jsx.queryStringToObject("http://blabla?foo=bar&number=1234")); 
console.log(jsx.queryStringToObject("a[fruits][red][]=strawberry"));
console.log(jsx.queryStringToObject("a[fruits][red][]=strawberry&a[1]=five&a[fruits][red][]=cherry&a[fruits][yellow][]=lemon&a[fruits][yellow][688]=banana"));

Bu şöyle bir şey çıkarır:

{ a: '1' }
{ a: '3' }
{ a: { '0': '1' } }
{ a: { '0': '1', '1': 'pomme' } }
{ a: { '0': 'one', '1': 'five' } }
{ foo: 'bar', number: '1234' }
{
  a: { fruits: { red: { '0': 'strawberry' } } }
}
{
  a: {
    '1': 'five',
    fruits: {
      red: { '0': 'strawberry', '1': 'cherry' },
      yellow: { '0': 'lemon', '688': 'banana' }
    }
  }
}

Not: locutus parse_str işlevini temel alır ( https://locutus.io/php/strings/parse_str/ ).

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.