Getirme isteğini kullanarak sorgu dizesini ayarlama


149

Yeni Getirme API'sını kullanmaya çalışıyorum :

Ben GETböyle bir istekte bulunuyorum:

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

Ancak, GETisteğe nasıl bir sorgu dizesi eklemek emin değilim . İdeal olarak, benzer bir GETistekte bulunmak URListiyorum:

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

Içinde jQuerybunu parametre {order_id: 1}olarak geçirerek yapabilirdi . Bunu yenisiyle yapmanın eşdeğer bir yolu var mı ?data$.ajax()Fetch API

Yanıtlar:


174

Mart 2017 Güncellemesi:

URL.searchParams desteği resmen Chrome 51 indi, ancak diğer tarayıcılar hala ihtiyaç polyfill .


Resmi sorgu parametreleri ile çalışmaya yolu URL'ye üzerine eklemek için adildir. Gönderen spec , bu bir örnektir:

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

Ancak, Chrome'un searchParamsbir URL'nin özelliğini (yazma sırasında) desteklediğinden emin değilim , bu nedenle bir üçüncü taraf kitaplığı veya kendi çözümünüzü kullanmak isteyebilirsiniz .

Nisan 2018 güncellemesi:

URLSearchParams yapıcısını kullanarak bir 2D dizi veya bir nesne atayabilir ve bunu url.searchtüm anahtarlar üzerinde döngü yapmak yerine ekleyebilirsiniz.

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: URLSearchParamsNodeJS'de de mevcuttur

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

1
Ayrıca developer.mozilla.org/en-US/docs/Web/API/URLSearchParams/… var , bu yazı itibariyle hala spesifikasyonlardan geçiyor ve henüz iyi desteklenmiyor. API, JS'den çok Java'ya benzer. : /
ericsoco

1
Arayüz desteği için bkz. Caniuse.com/#feat=urlsearchparamsURLSearchParams ; Ben ediyorum varsayalım (% 100 emin değilim gerçi) kırmızı tarayıcılar tam kendisi için tarayıcılar olduğunu URLnesneler olmaz .searchParamsözelliği. Önemlisi, Edge'in hala desteği yok.
Mark Amery

1
Belgelerden: "Bir URLSearchParams örneği kullanmanın kullanımdan kaldırıldığını unutmayın; yakında tarayıcılar yalnızca init için bir USVString kullanır." kaynak: developer.mozilla.org/tr-TR/docs/Web/API/URLSearchParams/…
pakman

1
new URLSearchParamsArrayözelliklerle düzgün çalışmıyor gibi görünüyor . Ben özelliğini dönüştürmek için beklenen array: [1, 2]etmek array[]=1&array[]=2, ancak onu dönüştürülür array=1,2. El ile appendyöntemini kullanarak sonuçlanır array=1&array=2, ancak params nesnesi üzerinde yineleme ve çok ergonomik değil, sadece dizi türleri için bunu yapmak gerekir.
erandros

1
Gerçekten de hata eklendi :) 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

Daha önce yanıtlandığı gibi, bu fetch-API ile spesifikasyon başına mümkün değildir . Ama şunu not etmeliyim:

Eğer açıksanız node, querystringpaket var. Nesneleri / sorgu dizelerini dizeleyebilir / ayrıştırabilir:

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

... sonra istemek için URL'ye ekleyin.


Ancak, yukarıdaki sorun, her zaman bir soru işareti ( ?) eklemek zorunda olmasıdır . Yani, başka bir yol parseyöntemi düğüm urlpaketinden kullanmak ve aşağıdaki gibi yapmaktır:

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

Bkz query. Https://nodejs.org/api/url.html#url_url_format_urlobj

Dahili olarak sadece yaptığı gibi bu mümkün değildir bu :

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

25

Kısa bir ES6 yaklaşımı:

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

URLSearchParams'ın toString () işlevi, sorgu bağımsız değişkenlerini URL'ye eklenebilecek bir dizeye dönüştürür. Bu örnekte, URL ile birleştirildiğinde toString () öğesi örtük olarak çağrılır.

IE URLSearchParams desteklemez, ama orada polyfills mevcut.

Düğüm kullanıyorsanız, URLSearchParams'ı sürüm 10'dan bu yana genel bir nesne olarak bulabilirsiniz. Eski sürümde bunu adresinde bulabilirsiniz require('url').URLSearchParams. Gerçek getirme API'si düğümün bir parçası değildir ve düğüm getirme gibi bir paket aracılığıyla eklenmesi gerekir .


9

Sen kullanabilirsiniz #stringifygelen sorgu dizesi

import { stringify } from 'query-string';

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

5

Belki bu daha iyidir:

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 - bir nesneyi querystring parametreleri olarak kodlar

/**
 * 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

Bunun mutlak aşikar olduğunu söylüyorum, ama en basitinden biri olarak bunu bir cevap olarak eklemeye değer olduğunu hissediyorum:

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

7
Bunun sadece tamsayı türleriyle güvenilir bir şekilde çalıştığını kabul etmeye değer. Eğer dizeleri, (arama kriterlerine gibi) özellikle kullanıcı tarafından sağlanan olanları kullanmak, o zaman aksi takdirde karakterler seviyorsanız garip sonuçlar alabilirsiniz, dize kaçmak zorunda /, +ya da &dizede görünür.
Malvineous

Özellikle isteği oluşturmak ve sonra fetch () çağrısı için el bir işlev kullanmak istiyorsanız, Request nesnesini kullanarak yardımcı olabilir, ancak ben bunu kullanmak "mutlak açık" olduğunu sanmıyorum. Ayrıca, url, yapılandırma seçeneklerinin nesne değişmezinde belirtilmemelidir; İstek yapıcısına ( developer.mozilla.org/en-US/docs/Web/API/Request/Request ) 1. parametre olarak ayrı olarak geçirilmelidir .
Gen1-1

3

Şablon değişmez değerleri de burada geçerli bir seçenektir ve birkaç avantaj sağlar.

Ham dizeler, sayılar, boole değerleri vb. Ekleyebilirsiniz:

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

Değişkenler ekleyebilirsiniz:

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

Mantık ve işlevler ekleyebilirsiniz:

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

Bildiğim kadarıyla daha büyük bir sorgu dizesi veri yapılandırma, ben bir dizeye bitiştirilmiş bir dizi kullanmayı seviyorum. Anlamak diğer yöntemlerden daha kolay buluyorum:

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

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

9
Bu yöntemle çok dikkatli olmalısınız, çünkü önce dizelerden URL'den kaçmaz. Yani, +veya benzeri bir karakter içeren bir değişken alırsanız &, beklendiği gibi çalışmaz ve düşündüğünüze göre farklı parametreler ve değerler elde edersiniz.
Malvineous

-1

Sadece Nativescript'in fetchModule ile çalışıyordu ve dize manipülasyonu kullanarak kendi çözümümü anladım. Sorgu dizesini URL'ye yavaş yavaş ekleyin. Sorgunun json nesnesi olarak iletildiği bir örnek (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.
}

Ben sorgu parametreleri birden çok sayıda üzerinde test ve bir cazibe gibi çalıştı :) Umarım bu birine yardımcı olur.


1
Bu, 3. taraf kütüphanelerini neden kullanmanız gerektiğine iyi bir örnektir - kodunuz iyi çalışıyor olabilir, ancak biri zaten çok daha iyi yaptı
refaelio

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.