Jak tworzyć parametry zapytania w JavaScript?

136

Czy istnieje sposób na utworzenie parametrów zapytania do wykonywania żądania GET w JavaScript?

Tak jak w Pythonie, który masz urllib.urlencode(), który pobiera słownik (lub listę dwóch krotek) i tworzy ciąg podobny do 'var1=value1&var2=value2'.

cnu
źródło

Odpowiedzi:

195

Proszę bardzo:

function encodeQueryData(data) {
   const ret = [];
   for (let d in data)
     ret.push(encodeURIComponent(d) + '=' + encodeURIComponent(data[d]));
   return ret.join('&');
}

Stosowanie:

const data = { 'first name': 'George', 'last name': 'Jetson', 'age': 110 };
const querystring = encodeQueryData(data);
Shog9
źródło
12
Podczas iteracji z for, użyj hasOwnProperty, aby zapewnić współdziałanie.
troelskn
3
@troelskn, dobra uwaga ... chociaż w tym przypadku ktoś musiałby rozszerzyć Object.prototype, aby go złamać, co jest dość złym pomysłem na początek.
Shog9,
1
@ Shog9 Dlaczego jest to zła idea?
Cesar Canassa,
@Cesar, patrz: stackoverflow.com/questions/3832617/… **
Shog9
Tylko mały szczegół, ale ret może być stały
Alkis Mavridis
92

URLSearchParams ma coraz większą obsługę przeglądarki.

const data = {
  var1: 'value1',
  var2: 'value2'
};

const searchParams = new URLSearchParams(data);

// searchParams.toString() === 'var1=value1&var2=value2'

Node.js oferuje moduł querystring .

const querystring = require('querystring');

const data = {
  var1: 'value1',
  var2: 'value2'
};

const searchParams = querystring.stringify(data);

// searchParams === 'var1=value1&var2=value2'
Andrew Palmer
źródło
1
Zdecydowanie czyste i nowoczesne podejście. Możesz też później swobodnie dzwonićsearchParams.append(otherData)
kano
URLSearchParams przeanalizuje białe znaki jako „+” zamiast „% 20”. Na przykład new URLSearchParams({ abc: 'a b c' }).toString()wynik'abc=a+b+c'
wrkwrk
82

funkcjonalny

function encodeData(data) {
    return Object.keys(data).map(function(key) {
        return [key, data[key]].map(encodeURIComponent).join("=");
    }).join("&");
}   
Manav
źródło
1
Niezłe! .map () został zaimplementowany w JavaScript 1.6, więc prawie wszystkie przeglądarki, nawet te starsze, obsługują go. Ale jak można się domyślić, IE nie oprócz IE 9+. Ale nie martw się, istnieje obejście. Źródło: developer.mozilla.org/en-US/docs/JavaScript/Reference/…
Akseli Palén
var data = { bloop1: true, bloop2: "something" }; var url = "https://something.com/?"; var params = encodeData(data); var finalUrl = url + params; // Is this the right use?Powinien produkować https://www.something.com/?bloop1=true&bloop2=something?
dylanh724
1
@DylanHunt: Tak…
Przemek
38

Zabba zamieścił w komentarzu do obecnie przyjętej odpowiedzi sugestię, że jest to dla mnie najlepsze rozwiązanie: użyj jQuery.param () .

Jeśli użyję jQuery.param()danych w pierwotnym pytaniu, kod będzie po prostu:

const params = jQuery.param({
    var1: 'value',
    var2: 'value'
});

Zmienna paramsbędzie

"var1=value&var2=value"

Bardziej skomplikowane przykłady, dane wejściowe i wyjściowe można znaleźć w dokumentacji jQuery.param () .

Kirby
źródło
10

Właśnie udostępniliśmy arg.js , projekt mający na celu rozwiązanie tego problemu raz na zawsze. Tradycyjnie było to bardzo trudne, ale teraz możesz:

var querystring = Arg.url({name: "Mat", state: "CO"});

I prace do czytania:

var name = Arg("name");

lub otrzymując całość:

var params = Arg.all();

a jeśli zależy ci na różnicy między ?query=truea #hash=truenastępnie możesz użyć metod Arg.query()i Arg.hash().

Mat Ryer
źródło
9

To powinno wystarczyć:

const createQueryParams = params => 
      Object.keys(params)
            .map(k => `${k}=${encodeURI(params[k])}`)
            .join('&');

Przykład:

const params = { name : 'John', postcode: 'W1 2DL'}
const queryParams = createQueryParams(params)

Wynik:

name=John&postcode=W1%202DL
noego
źródło
1
Później zdałem sobie sprawę, że jest to właściwie nieco inna wersja odpowiedzi @ manav poniżej. Ale tak czy inaczej, nadal może być preferowane dla składni ES6.
noego
1
Przede wszystkim nie kodujesz kluczy. Powinieneś także użyć encodeURIComponent()zamiast encodeURI. Przeczytaj o różnicy .
Przemek
9

ES2017 (ES8)

Wykorzystanie Object.entries(), które zwraca tablicę [key, value]par obiektów. Na przykład, {a: 1, b: 2}ponieważ powróci [['a', 1], ['b', 2]]. Nie jest obsługiwany (i nie będzie) tylko przez IE.

Kod:

const buildURLQuery = obj =>
      Object.entries(obj)
            .map(pair => pair.map(encodeURIComponent).join('='))
            .join('&');

Przykład:

buildURLQuery({name: 'John', gender: 'male'});

Wynik:

"name=John&gender=male"
Przemek
źródło
8

Jeśli używasz Prototype, istnieje Form.serialize

Jeśli używasz jQuery, istnieje Ajax / serialize

Nie znam żadnych niezależnych funkcji, które mogłyby to osiągnąć, ale wyszukiwanie go w Google dało kilka obiecujących opcji, jeśli obecnie nie korzystasz z biblioteki. Jeśli nie, to naprawdę powinieneś, bo one są niebem.

Paolo Bergantino
źródło
6
jQuery.param () pobiera obiekt i przekształca go w ciąg zapytania GET (ta funkcja lepiej pasuje do pytania).
azurkin
5

Chciałbym powrócić do tego prawie 10-letniego pytania. W erze gotowego programowania najlepiej jest skonfigurować projekt za pomocą menedżera zależności ( npm). Istnieje cała branża bibliotek, które kodują ciągi zapytań i zajmują się wszystkimi przypadkami brzegowymi. To jeden z bardziej popularnych -

https://www.npmjs.com/package/query-string

pscl
źródło
Bardzo nieokreślona odpowiedź.
masterxilo
2

Mała modyfikacja maszynopisu:

  public encodeData(data: any): string {
    return Object.keys(data).map((key) => {
      return [key, data[key]].map(encodeURIComponent).join("=");
    }).join("&");
  }
Clayton KN Passos
źródło
0

Poprawiłem funkcję shog9 do obsługi wartości tablicowych

function encodeQueryData(data) {
    const ret = [];
    for (let d in data) {
        if (typeof data[d] === 'object' || typeof data[d] === 'array') {
            for (let arrD in data[d]) {
                ret.push(`${encodeURIComponent(d)}[]=${encodeURIComponent(data[d][arrD])}`)
            }
        } else if (typeof data[d] === 'null' || typeof data[d] === 'undefined') {
            ret.push(encodeURIComponent(d))
        } else {
            ret.push(`${encodeURIComponent(d)}=${encodeURIComponent(data[d])}`)
        }

    }
    return ret.join('&');
}

Przykład

let data = {
  user: 'Mark'
  fruits: ['apple', 'banana']
}

encodeQueryData(data) // user=Mark&fruits[]=apple&fruits[]=banana
Roman Morozov
źródło
-11

Ten wątek wskazuje na kod służący do ucieczki adresów URL w php. Jest escape()i unescape()który wykona większość pracy, ale musisz dodać kilka dodatkowych rzeczy.

function urlencode(str) {
str = escape(str);
str = str.replace('+', '%2B');
str = str.replace('%20', '+');
str = str.replace('*', '%2A');
str = str.replace('/', '%2F');
str = str.replace('@', '%40');
return str;
}

function urldecode(str) {
str = str.replace('+', ' ');
str = unescape(str);
return str;
}
Kibbee
źródło
3
encodeURIComponent obsługuje to i nie używa niepoprawnie znaku + jako spacji.
AnthonyWJones