Mam taki ciąg:
abc=foo&def=%5Basf%5D&xyz=5
Jak mogę przekonwertować go na taki obiekt JavaScript?
{
abc: 'foo',
def: '[asf]',
xyz: 5
}
Mam taki ciąg:
abc=foo&def=%5Basf%5D&xyz=5
Jak mogę przekonwertować go na taki obiekt JavaScript?
{
abc: 'foo',
def: '[asf]',
xyz: 5
}
Odpowiedzi:
Edytować
Ta edycja poprawia i wyjaśnia odpowiedź na podstawie komentarzy.
Przykład
Analizuj
abc=foo&def=%5Basf%5D&xyz=5
w pięciu krokach:abc=foo","def=[asf]","xyz=5
abc":"foo","def":"[asf]","xyz":"5
{"abc":"foo","def":"[asf]","xyz":"5"}
który jest legalny JSON.
Ulepszone rozwiązanie pozwala na więcej znaków w ciągu wyszukiwania. Wykorzystuje funkcję rewitalizującą do dekodowania URI:
Przykład
daje
Oryginalna odpowiedź
Jednowarstwowy:
źródło
JSON.parse('{"' + decodeURI(location.search.substring(1).replace(/&/g, "\",\"").replace(/=/g, "\":\"")) + '"}')
2020 ES6 / 7/8 i przy podejściu
Począwszy od ES6 i później, Javascript oferuje kilka konstrukcji w celu stworzenia wydajnego rozwiązania tego problemu.
Obejmuje to używanie URLSearchParams i iteratorów
Jeśli Twój przypadek użycia wymaga faktycznej konwersji go na obiekt, możesz zaimplementować następującą funkcję:
Podstawowe demo
Za pomocą Object.fromEntries i rozprzestrzeniania
Możemy użyć Object.fromEntries (który jest obecnie na etapie 4), zastępując
paramsToObject
goObject.fromEntries(entries)
.Ponieważ
URLParams
zwraca obiekt iterowalny , użycie operatora rozkładania zamiast wywołania.entries
da również wpisy według jego specyfikacji:Uwaga: Wszystkie wartości są automatycznie ciągami zgodnie ze specyfikacją URLSearchParams
Wiele takich samych kluczy
Jak @siipe wskazał, ciągi zawierające wiele wartości tego samego klawisza będzie zmuszany do ostatniej dostępnej wartości:
foo=first_value&foo=second_value
będzie w istocie stają się:{foo: "second_value"}
.Zgodnie z tą odpowiedzią: https://stackoverflow.com/a/1746566/1194694 nie ma żadnej specyfikacji dotyczącej decydowania, co z tym zrobić, a każda struktura może zachowywać się inaczej.
Typowym przypadkiem użycia będzie połączenie dwóch tych samych wartości w tablicę, w wyniku czego obiekt wyjściowy stanie się:
Można to osiągnąć za pomocą następującego kodu:
źródło
search string
parser - do tego został zaprojektowany, niezależnie od tego, czy jest powiązany z adresem URLObject.fromEntries
nie działa dla powtarzających się klawiszy. Jeśli spróbujemy zrobić coś takiego?foo=bar1&foo=bar2
, dostaniemy tylko{ foo: 'bar2' }
. Na przykład obiekt żądania Node.js analizuje go jako{ foo: ['bar1', 'bar2'] }
let temp={};Object.keys(params).map(key=>{temp[key]=urlParams.getAll(key)})
ES6 jedna wkładka. Czysty i prosty.
W twoim konkretnym przypadku byłoby to:
źródło
"http://place.com?foo=bar&hello=%40world&showThing"
produkuje{ hello: "@world", http://place.com?foo: "bar", showThing: "" }
?someValue=false
staje się{ someValue: "false" }
?foo=bar1&foo=bar2
, dostaniemy tylko{ foo: 'bar2' }
. Obiekt żądania Node.js analizuje go jako{ foo: ['bar1', 'bar2'] }
location.search
Podziel,
&
aby uzyskać pary nazwa / wartość, a następnie podziel każdą parę=
. Oto przykład:Inne podejście z wykorzystaniem wyrażeń regularnych:
Jest to dostosowane z „Szukaj i nie zamieniaj” Johna Resiga .
źródło
Zwięzłe rozwiązanie:
źródło
Zaproponowane przeze mnie rozwiązania nie obejmują bardziej złożonych scenariuszy.
Musiałem przekonwertować ciąg zapytania jak
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
w obiekt taki jak:
LUB:
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
W:
Skompilowałem i zaadaptowałem wiele rozwiązań w jedno, które faktycznie działa:
KOD:
źródło
obj=encodeURIComponent(JSON.stringify({what:{ever:','},i:['like']}))
.To jest prosta wersja, oczywiście chcesz dodać trochę sprawdzania błędów:
źródło
JSON.parse('{"' + decodeURIComponent(query.replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g,'":"') + '"}'));
działa dla mniename[]=test1&name[]=test2
i zaowocujename[]=test2
Znalazłem $ .String.deparam jako najbardziej kompletne gotowe rozwiązanie (może wykonywać zagnieżdżone obiekty itp.). Sprawdź dokumentację .
źródło
Podejście One-Liner 2019
W konkretnym przypadku:
W bardziej ogólnym przypadku, gdy ktoś chce parsować parametry zapytania do obiektu:
Jeśli nie możesz użyć Object.fromEntries, zadziała to również:
źródło
[...new URLSearchParams(window.location.search)].reduce((o, i) => ({ ...o, [i[0]]: i[1] }), {});
"http://place.com?foo=bar&hello=%40world&showThing
produkuje{ hello: "@world", http://place.com?foo: "bar", showThing: "" }
. Spróbuj dodaćstr.split("?").pop()
Kolejne rozwiązanie oparte na najnowszym standardzie URLSearchParams ( https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams )
Pamiętaj, że z tego rozwiązania korzysta
Array.from ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from )
oraz _.fromPairs ( https://lodash.com/docs#fromPairs ) lodash dla uproszczenia.
Stworzenie bardziej kompatybilnego rozwiązania powinno być łatwe, ponieważ masz dostęp do iteratora searchParams.entries () .
źródło
Miałem ten sam problem, wypróbowałem tutaj rozwiązania, ale żadne z nich tak naprawdę nie działało, ponieważ miałem tablice w parametrach URL, takie jak to:
Skończyło się więc pisaniem własnej funkcji JS, która tworzy tablicę z parametru w URI:
źródło
if(chunk[0].search("\\[\\]") !== -1) {
tymchunk[0]=chunk[0].replace(/\[\]$/,'');
const
zamiast,var
ponieważ ktoś może to zrobić,createObjFromURI = 'some text'
a następnie zepsuje kod. jeśli użyjesz,const
wtedy ktoś uruchomionycreateObjFromURI = 'some text'
spowoduje błąd, nie może przypisać wartości do zmiennej stałejKorzystanie z ES6, interfejsu API URL i interfejsu API URLSearchParams.
źródło
ES6 jedna linijka (jeśli możemy to tak nazwać widząc długą linię)
[...new URLSearchParams(location.search).entries()].reduce((prev, [key,val]) => {prev[key] = val; return prev}, {})
źródło
cur
dla większej przejrzystości..reduce((prev, [key, val]) => {prev[key] = val})
Całkiem łatwe korzystanie z
URLSearchParams
JavaScript Web API,Przydatne linki
źródło
W przypadku Node JS można użyć interfejsu API Node JS
querystring
:Dokumentacja: https://nodejs.org/api/querystring.html
źródło
Nie ma natywnego rozwiązania, o którym wiem. Dojo ma wbudowaną metodę unserializacji, jeśli używasz tej platformy przez przypadek.
W przeciwnym razie możesz go zaimplementować raczej po prostu:
edycja: dodano decodeURIComponent ()
źródło
Istnieje lekka biblioteka o nazwie YouAreI.js, która została przetestowana i sprawia, że jest to naprawdę łatwe.
źródło
Jeden z najprostszych sposobów, aby to zrobić za pomocą interfejsu URLSearchParam.
Poniżej znajduje się działający fragment kodu:
źródło
To wydaje się być najlepszym rozwiązaniem, ponieważ uwzględnia wiele parametrów o tej samej nazwie.
Później postanowiłem przekonwertować go również na wtyczkę jQuery ...
Teraz pierwszy zaakceptuje tylko parametry, ale wtyczka jQuery zajmie cały adres URL i zwróci parametry serializowane.
źródło
Oto jeden, którego używam:
Podstawowe użycie, np.
?a=aa&b=bb
Object {a: "aa", b: "bb"}
Zduplikowane parametry, np.
?a=aa&b=bb&c=cc&c=potato
Object {a: "aa", b: "bb", c: ["cc","potato"]}
Brakujące klucze, np.
?a=aa&b=bb&=cc
Object {a: "aa", b: "bb"}
Brakujące wartości, np.
?a=aa&b=bb&c
Object {a: "aa", b: "bb"}
Powyższe rozwiązania JSON / regex generują błąd składniowy na tym zwariowanym adresie URL:
?a=aa&b=bb&c=&=dd&e
Object {a: "aa", b: "bb", c: ""}
źródło
Oto moja szybka i brudna wersja, w zasadzie polega ona na podzieleniu parametrów adresu URL oddzielonych „&” na elementy tablicy, a następnie iteracji po tej tablicy, dodając pary klucz / wartość oddzielone przez „=” do obiektu. Używam decodeURIComponent () do przetłumaczenia zakodowanych znaków na ich normalne ciągi znaków (więc% 20 staje się spacją,% 26 staje się „&” itd.):
przykład:
zwroty
Jedynym problemem jest to, że xyz jest ciągiem, a nie liczbą (ze względu na użycie decodeURIComponent ()), ale poza tym nie jest to zły punkt początkowy.
źródło
źródło
Babel
pomocą możesz to zrobić dobrze w innym środowiskuKorzystanie z phpjs
źródło
Opierając się na odpowiedzi Mike'a Causera, stworzyłem tę funkcję, która bierze pod uwagę wiele parametrów z tym samym kluczem (
foo=bar&foo=baz
), a także parametry oddzielone przecinkami (foo=bar,baz,bin
). Pozwala także wyszukać określony klucz zapytania.Przykładowe dane wejściowe:
foo.html?foo=bar&foo=baz&foo=bez,boz,buz&bar=1,2,3
Przykładowe dane wyjściowe
źródło
Jeśli używasz URI.js, możesz użyć:
https://medialize.github.io/URI.js/docs.html#static-parseQuery
źródło
źródło
PIERWSZE POTRZEBUJESZ OKREŚLIĆ CO ZROBIĆ:
Następnie przeczytaj:
i użyj takich jak:
źródło
Musiałem poradzić sobie również z
+
częścią zapytania w adresie URL ( decodeURIComponent nie ), więc dostosowałem kod Wolfganga, aby był:W moim przypadku używam jQuery, aby uzyskać parametry formularza gotowe do adresu URL, a następnie tę sztuczkę, aby zbudować z niego obiekt, a następnie mogę łatwo zaktualizować parametry obiektu i odbudować adres URL zapytania, np .:
źródło
Robię to w ten sposób:
źródło
Jeśli potrzebujesz rekurencji, możesz użyć małej biblioteki js-extension-ling .
Spowoduje to wyświetlenie czegoś takiego:
Uwaga: jest oparty na funkcji parse_str locutus ( https://locutus.io/php/strings/parse_str/ ).
źródło