Festlegen der Abfragezeichenfolge mithilfe der Fetch GET-Anforderung

147

Ich versuche, die neue Fetch-API zu verwenden :

Ich mache eine GETAnfrage wie folgt:

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

Ich bin mir jedoch nicht sicher, wie ich der GETAnfrage eine Abfragezeichenfolge hinzufügen soll . Idealerweise möchte ich in der Lage sein, eine GETAnfrage an ein URLLike zu richten:

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

In jQuerykönnte ich dies tun, indem ich {order_id: 1}als dataParameter von übergebe $.ajax(). Gibt es eine gleichwertige Möglichkeit, dies mit dem Neuen zu tun Fetch API?

mylescc
quelle

Antworten:

173

Update März 2017:

Die Unterstützung für URL.searchParams ist offiziell in Chrome 51 gelandet, andere Browser benötigen jedoch weiterhin eine Polyfüllung .


Die offizielle Methode zum Arbeiten mit Abfrageparametern besteht darin, sie der URL hinzuzufügen. Aus der Spezifikation ist dies ein Beispiel:

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(/* … */)

Ich bin mir jedoch nicht sicher, ob Chrome die searchParamsEigenschaft einer URL (zum Zeitpunkt des Schreibens) unterstützt. Daher möchten Sie möglicherweise entweder eine Bibliothek eines Drittanbieters oder eine eigene Lösung verwenden .

Update April 2018:

Mit dem URLSearchParams-Konstruktor können Sie ein 2D-Array oder ein Objekt zuweisen und dies einfach dem zuweisen, url.searchanstatt alle Schlüssel zu durchlaufen und sie anzuhängen

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)

Nebenbemerkung: URLSearchParamsist auch in NodeJS verfügbar

const { URL, URLSearchParams } = require('url');
CodingIntrigue
quelle
1
Es gibt auch developer.mozilla.org/en-US/docs/Web/API/URLSearchParams/… , obwohl es zum jetzigen Zeitpunkt immer noch den Weg durch die Spezifikation findet und noch nicht gut unterstützt wird. Und die API ähnelt eher Java als JS. : /
ericsoco
1
Informationen zur Unterstützung der URLSearchParamsBenutzeroberfläche finden Sie unter caniuse.com/#feat=urlsearchparams . Ich würde annehmen (obwohl ich nicht 100% sicher bin), dass die Browser in Rot genau die Browser sind, für die URLObjekte die .searchParamsEigenschaft nicht haben . Wichtig ist, dass Edge immer noch keine Unterstützung bietet.
Mark Amery
1
Aus der Dokumentation: "Beachten Sie, dass die Verwendung einer URLSearchParams-Instanz veraltet ist. In Kürze verwenden Browser nur noch einen USVString für den Init." Quelle: developer.mozilla.org/en-US/docs/Web/API/URLSearchParams/…
pakman
1
new URLSearchParamsscheint mit ArrayEigenschaften nicht richtig zu funktionieren . Ich habe erwartet, dass es die Eigenschaft array: [1, 2]in array[]=1&array[]=2konvertiert, aber konvertiert in array=1,2. Die manuelle Verwendung der appendMethode führt zwar dazu array=1&array=2, aber ich müsste über das params-Objekt iterieren und dies nur für Array-Typen tun, die nicht sehr ergonomisch sind.
Erandros
1
Es wurde tatsächlich irrtümlich hinzugefügt :) 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)
  });
Sudharshan
quelle
26

Wie bereits beantwortet, ist dies per Spezifikation mit der fetch-API noch nicht möglich . Aber ich muss beachten:

Wenn Sie eingeschaltet sind node, gibt es das querystringPaket. Es kann Objekte / Abfrageringe stringifizieren / analysieren:

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

... dann hängen Sie es einfach an die URL an, um es anzufordern.


Das Problem mit dem oben genannten ist jedoch, dass Sie immer ein Fragezeichen ( ?) voranstellen müssen . Eine andere Möglichkeit besteht darin, die parseMethode aus dem Knotenpaket urlwie folgt zu verwenden:

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

Siehe queryunter https://nodejs.org/api/url.html#url_url_format_urlobj

Dies ist möglich, da es intern genau dies tut :

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

Ein prägnanter ES6-Ansatz:

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

Die Funktion toString () von URLSearchParam konvertiert die Abfrageargumente in eine Zeichenfolge, die an die URL angehängt werden kann. In diesem Beispiel wird toString () implizit aufgerufen, wenn es mit der URL verkettet wird.

IE unterstützt diese Funktion nicht, es sind jedoch Polyfills verfügbar.

Scotty Jamison
quelle
5

Vielleicht ist das besser:

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);
});
Bin HOU
quelle
5

encodeQueryString - Codiert ein Objekt als Querystring-Parameter

/**
 * 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"
ChaseMoskal
quelle
5

Ich weiß, dass dies das absolut Offensichtliche ist, aber ich denke, es lohnt sich, dies als Antwort hinzuzufügen, da es das einfachste von allen ist:

var orderId = 1;
var request = new Request({
  url: 'http://myapi.com/orders?order_id=' + orderId,
  method: 'GET'
});
fetch(request);
Evert
quelle
7
Es lohnt sich zu qualifizieren, dass dies nur mit ganzzahligen Typen zuverlässig funktioniert. Wenn Sie Zeichenfolge verwenden, vor allem vom Benutzer bereitgestellte diejenigen (wie Suchkriterien) , dann müssen Sie die Zeichenfolge entkommen, sonst kann man ungeradee Ergebnisse, wenn Zeichen wie /, +oder &in der Zeichenfolge erscheinen.
Malvineous
Die Verwendung des Request-Objekts kann hilfreich sein, insbesondere wenn Sie eine Funktion zum Erstellen der Anforderung verwenden und diese dann an den Aufruf von fetch () übergeben möchten, aber ich denke nicht, dass die Verwendung "absolut offensichtlich" ist. Außerdem sollte die URL nicht im Objektliteral der Konfigurationsoptionen angegeben werden. Es sollte separat als 1. Parameter an den Request-Konstruktor übergeben werden ( developer.mozilla.org/en-US/docs/Web/API/Request/Request ).
Gen1-1
3

Vorlagenliterale sind auch hier eine gültige Option und bieten einige Vorteile.

Sie können rohe Zeichenfolgen, Zahlen, boolesche Werte usw. einschließen:

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

Sie können Variablen einschließen:

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

Sie können Logik und Funktionen einschließen:

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

Was die Strukturierung der Daten einer größeren Abfragezeichenfolge angeht, verwende ich gerne ein Array, das mit einer Zeichenfolge verknüpft ist. Ich finde es leichter zu verstehen als einige der anderen Methoden:

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

let request = new Request(`https://example.com/?${queryString}`, {
  method: 'GET'
});
Pat Kearns
quelle
8
Sie müssen bei dieser Methode sehr vorsichtig sein, da die Zeichenfolgen nicht zuerst per URL-Escapezeichen versehen werden. Wenn Sie also eine Variable erhalten, die ein Zeichen wie +oder enthält, &funktioniert sie nicht wie erwartet und Sie erhalten andere Parameter und Werte als gedacht.
Malvineous
-1

Ich habe gerade mit fetchModule von Nativescript gearbeitet und mithilfe von String-Manipulationen meine eigene Lösung gefunden. Hängen Sie die Abfragezeichenfolge Stück für Stück an die URL an. Hier ist ein Beispiel, in dem die Abfrage als JSON-Objekt übergeben wird (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.
}

Ich habe dies über mehrere Abfrageparameter getestet und es hat wie ein Zauber funktioniert :) Ich hoffe, das hilft jemandem.

Amjad Abujamous
quelle
1
Dies ist ein gutes Beispiel dafür, warum Sie
Bibliotheken von