Impostazione della stringa di query mediante la richiesta GET Fetch


148

Sto cercando di utilizzare la nuova API Fetch :

Sto facendo una GETrichiesta come questa:

var request = new Request({
  url: 'http://myapi.com/orders',
  method: 'GET'
});
fetch(request);

Tuttavia, non sono sicuro di come aggiungere una stringa di query alla GETrichiesta. Idealmente, voglio essere in grado di fare una GETrichiesta a un URLsimile:

'http://myapi.com/orders?order_id=1'

In jQuerypotrei farlo passando {order_id: 1}il dataparametro di $.ajax(). Esiste un modo equivalente per farlo con il nuovo Fetch API?

Risposte:


173

Aggiornamento marzo 2017:

Il supporto URL.searchParams è arrivato ufficialmente in Chrome 51, ma altri browser richiedono ancora un polyfill .


Il modo ufficiale di lavorare con i parametri della query è semplicemente aggiungerli all'URL. Dalle specifiche , questo è un esempio:

var url = new URL("https://geo.example.org/api"),
    params = {lat:35.696233, long:139.570431}
Object.keys(params).forEach(key => url.searchParams.append(key, params[key]))
fetch(url).then(/* … */)

Tuttavia, non sono sicuro che Chrome supporti la searchParamsproprietà di un URL (al momento della stesura), quindi potresti voler utilizzare una libreria di terze parti o una soluzione roll-your-own .

Aggiornamento aprile 2018:

Con l'uso della funzione di costruzione URLSearchParams è possibile assegnare un array 2D o un oggetto e assegnarlo a url.searchinvece di scorrere su tutte le chiavi e aggiungerle

var url = new URL('https://sl.se')

var params = {lat:35.696233, long:139.570431} // or:
var params = [['lat', '35.696233'], ['long', '139.570431']]

url.search = new URLSearchParams(params).toString();

fetch(url)

Sidenote: URLSearchParamsè disponibile anche in NodeJS

const { URL, URLSearchParams } = require('url');

1
C'è anche developer.mozilla.org/en-US/docs/Web/API/URLSearchParams/… , anche se al momento in cui scrivo si sta facendo strada attraverso le specifiche e non è ancora ben supportato. E l'API è più simile a Java che a JS. : /
ericsoco,

1
Vedi caniuse.com/#feat=urlsearchparams per supporto per l' URLSearchParamsinterfaccia; Mi assumo (anche se non sono sicuro al 100%) che i browser in rosso ci sono esattamente i browser per i quali URLgli oggetti non avranno la .searchParamsproprietà. È importante sottolineare che Edge non ha ancora supporto.
Mark Amery,

1
Dalla documentazione: "Nota che l'utilizzo di un'istanza URLSearchParams è obsoleto; presto i browser useranno solo una USVString per l'init". fonte: developer.mozilla.org/en-US/docs/Web/API/URLSearchParams/…
pakman

1
new URLSearchParamsnon sembra funzionare correttamente con le Arrayproprietà. Mi aspettavo che convertisse la proprietà array: [1, 2]in array[]=1&array[]=2, ma la convertissi in array=1,2. appendNe consegue l'utilizzo manuale del metodo array=1&array=2, ma dovrei iterare sull'oggetto params e farlo solo per i tipi di array, non molto ergonomico.
Erandros,

1
È stato effettivamente aggiunto per errore :) github.com/mdn/sprints/issues/2856
CodingIntrigue

30
let params = {
  "param1": "value1",
  "param2": "value2"
};

let query = Object.keys(params)
             .map(k => encodeURIComponent(k) + '=' + encodeURIComponent(params[k]))
             .join('&');

let url = 'https://example.com/search?' + query;

fetch(url)
  .then(data => data.text())
  .then((text) => {
    console.log('request succeeded with JSON response', text)
  }).catch(function (error) {
    console.log('request failed', error)
  });

26

Come già risposto, questo non è ancora possibile per le specifiche con fetch-API. Ma devo notare:

Se sei acceso node, c'è il querystringpacchetto. Può stringere / analizzare oggetti / stringhe di query:

var querystring = require('querystring')
var data = { key: 'value' }
querystring.stringify(data) // => 'key=value'

... quindi basta aggiungerlo all'URL per richiedere.


Tuttavia, il problema con quanto sopra è che devi sempre anteporre un punto interrogativo ( ?). Quindi, un altro modo è usare il parsemetodo dal urlpacchetto nodes e farlo come segue:

var url = require('url')
var data = { key: 'value' }
url.format({ query: data }) // => '?key=value'

Vedere querya https://nodejs.org/api/url.html#url_url_format_urlobj

Questo è possibile, come fa internamente solo questo :

search = obj.search || (
    obj.query && ('?' + (
        typeof(obj.query) === 'object' ?
        querystring.stringify(obj.query) :
        String(obj.query)
    ))
) || ''

25

Un approccio sintetico ES6:

fetch('https://example.com?' + new URLSearchParams({
    foo: 'value',
    bar: 2,
}))

La funzione toString () di URLSearchParam convertirà gli argomenti della query in una stringa che può essere aggiunta all'URL. In questo esempio, toString () viene chiamato implicitamente quando viene concatenato con l'URL.

IE non supporta questa funzionalità, ma sono disponibili polyfill .


9

È possibile utilizzare #stringifydalla stringa di query

import { stringify } from 'query-string';

fetch(`https://example.org?${stringify(params)}`)

5

Forse è meglio:

const withQuery = require('with-query');

fetch(withQuery('https://api.github.com/search/repositories', {
  q: 'query',
  sort: 'stars',
  order: 'asc',
}))
.then(res => res.json())
.then((json) => {
  console.info(json);
})
.catch((err) => {
  console.error(err);
});

5

encodeQueryString: codifica un oggetto come parametri querystring

/**
 * Encode an object as url query string parameters
 * - includes the leading "?" prefix
 * - example input — {key: "value", alpha: "beta"}
 * - example output — output "?key=value&alpha=beta"
 * - returns empty string when given an empty object
 */
function encodeQueryString(params) {
    const keys = Object.keys(params)
    return keys.length
        ? "?" + keys
            .map(key => encodeURIComponent(key)
                + "=" + encodeURIComponent(params[key]))
            .join("&")
        : ""
}

encodeQueryString({key: "value", alpha: "beta"})
 //> "?key=value&alpha=beta"

5

So che questo sta affermando l'assoluto ovvio, ma penso che valga la pena aggiungerlo come risposta in quanto è il più semplice di tutti:

var orderId = 1;
var request = new Request({
  url: 'http://myapi.com/orders?order_id=' + orderId,
  method: 'GET'
});
fetch(request);

7
Vale la pena qualificare che funziona in modo affidabile solo con tipi interi. Se si utilizzano le stringhe, in particolare quelli forniti dall'utente (come criteri di ricerca) poi si deve fuggire la stringa, altrimenti si possono ottenere risultati strani personaggi come se /, +o &appaiono nella stringa.
Malvineous,

L'uso dell'oggetto Request può essere d'aiuto, specialmente se vuoi usare una funzione per creare la richiesta e poi passarla alla chiamata fetch (), ma non credo che usarla sia "assolutamente ovvio". Inoltre, l'URL non deve essere specificato nell'oggetto letterale delle opzioni di configurazione; dovrebbe essere passato separatamente come primo parametro al costruttore della richiesta ( developer.mozilla.org/en-US/docs/Web/API/Request/Request ).
Gen1-1

3

Anche i letterali modello sono un'opzione valida qui e offrono alcuni vantaggi.

Puoi includere stringhe, numeri, valori booleani grezzi, ecc.:

    let request = new Request(`https://example.com/?name=${'Patrick'}&number=${1}`);

Puoi includere variabili:

    let request = new Request(`https://example.com/?name=${nameParam}`);

Puoi includere logica e funzioni:

    let request = new Request(`https://example.com/?name=${nameParam !== undefined ? nameParam : getDefaultName() }`);

Per quanto riguarda la strutturazione dei dati di una stringa di query più grande, mi piace usare un array concatenato a una stringa. Trovo più facile da capire rispetto ad alcuni degli altri metodi:

let queryString = [
  `param1=${getParam(1)}`,
  `param2=${getParam(2)}`,
  `param3=${getParam(3)}`,
].join('&');

let request = new Request(`https://example.com/?${queryString}`, {
  method: 'GET'
});

9
Devi stare molto attento con questo metodo perché non sfugge all'URL prima delle stringhe. Quindi se ottieni una variabile che contiene un carattere simile +o &non funzionerà come previsto e finirai con parametri e valori diversi da quello che pensavi.
Malvineous,

-1

Stavo solo lavorando con il modulo fetch di Nativescript e ho scoperto la mia soluzione usando la manipolazione delle stringhe. Aggiunge la stringa di query bit per bit all'URL. Ecco un esempio in cui la query viene passata come oggetto json (query = {order_id: 1}):

function performGetHttpRequest(fetchLink='http://myapi.com/orders', query=null) {
    if(query) {
        fetchLink += '?';
        let count = 0;
        const queryLength = Object.keys(query).length;
        for(let key in query) {
            fetchLink += key+'='+query[key];
            fetchLink += (count < queryLength) ? '&' : '';
            count++;
        }
    }
    // link becomes: 'http://myapi.com/orders?order_id=1'
    // Then, use fetch as in MDN and simply pass this fetchLink as the url.
}

Ho provato questo su un numero multiplo di parametri di query e ha funzionato come un fascino :) Spero che questo aiuti qualcuno.


1
Questo è un buon esempio del motivo per cui dovresti usare librerie di terze parti - il tuo codice potrebbe funzionare bene, ma qualcuno l'ha già fatto molto meglio
refaelio

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.