Mengatur string kueri menggunakan Fetch GET request


148

Saya mencoba menggunakan API Ambil baru :

Saya membuat GETpermintaan seperti ini:

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

Namun, saya tidak yakin cara menambahkan string kueri ke GETpermintaan. Idealnya, saya ingin bisa membuatGET permintaan URLseperti:

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

Di jQuerysaya bisa melakukan ini dengan melewati {order_id: 1}sebagai dataparameter $.ajax(). Apakah ada cara yang setara untuk melakukan itu dengan yang baruFetch API ?

Jawaban:


173

Pembaruan Maret 2017:

Dukungan URL.searchParams telah secara resmi mendarat di Chrome 51, tetapi browser lain masih memerlukan polyfill .


Cara resmi untuk bekerja dengan parameter kueri adalah menambahkannya ke URL. Dari spec , ini adalah contoh:

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

Namun, saya tidak yakin Chrome mendukung searchParamsproperti URL (pada saat penulisan) sehingga Anda mungkin ingin menggunakan pustaka pihak ketiga atau menggulung solusi Anda sendiri .

Pembaruan April 2018:

Dengan menggunakan konstruktor URLSearchParams, Anda dapat menetapkan array 2D atau objek dan hanya menetapkannya ke url.searchalih - alih memutar semua kunci dan menambahkannya

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: URLSearchParamsjuga tersedia di NodeJS

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

1
Ada juga developer.mozilla.org/en-US/docs/Web/API/URLSearchParams/… , sampai saat tulisan ini dibuat, masih melalui spec, dan belum didukung dengan baik. Dan API lebih seperti Java daripada JS. : /
ericsoco

1
Lihat caniuse.com/#feat=urlsearchparams untuk dukungan untuk URLSearchParamsantarmuka; Saya akan berasumsi (meskipun saya tidak 100% yakin) bahwa browser berwarna merah sebenarnya ada browser yang URLobjeknya tidak memiliki .searchParamsproperti. Yang penting, Edge masih tidak memiliki dukungan.
Mark Amery

1
Dari dokumentasi: "Perhatikan bahwa penggunaan instance URLSearchParams sudah ditinggalkan; segera browser hanya akan menggunakan USVString untuk init." sumber: developer.mozilla.org/en-US/docs/Web/API/URLSearchParams/…
pakman

1
new URLSearchParamstampaknya tidak berfungsi dengan benar dengan Arrayproperti. Saya mengharapkannya untuk mengubah properti array: [1, 2]menjadi array[]=1&array[]=2, tetapi mengubahnya menjadi array=1,2. Secara manual menggunakan appendmetode itu menghasilkan array=1&array=2, tapi saya harus beralih lebih dari objek params, dan melakukannya hanya untuk jenis array, tidak sangat ergonomis.
erandros

1
Itu memang ditambahkan dalam kesalahan :) 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

Seperti yang sudah dijawab, ini per spec tidak mungkin dengan fetch -API, belum. Tapi saya harus perhatikan:

Jika Anda aktif node, ada querystringpaketnya. Itu dapat merender / mengurai objek / querystrings:

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

... lalu tambahkan saja ke url untuk meminta.


Namun, masalah dengan hal di atas adalah, bahwa Anda harus selalu menambahkan tanda tanya ( ?). Jadi, cara lain adalah dengan menggunakan parsemetode dari urlpaket node dan melakukannya sebagai berikut:

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

Lihat querydi https://nodejs.org/api/url.html#url_url_format_urlobj

Ini dimungkinkan, seperti yang dilakukan secara internal ini :

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

25

Pendekatan ES6 ringkas:

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

Fungsi toString () URLSearchParam akan mengubah argumen kueri menjadi string yang dapat ditambahkan ke URL. Dalam contoh ini, toString () dipanggil secara implisit ketika ia digabungkan dengan URL.

IE tidak mendukung fitur ini, tetapi ada polyfill yang tersedia.


9

Anda dapat menggunakan #stringifydari string kueri

import { stringify } from 'query-string';

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

5

Mungkin ini lebih baik:

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 - mengkodekan objek sebagai parameter 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

Saya tahu ini menyatakan yang paling jelas, tetapi saya merasa perlu menambahkan ini sebagai jawaban karena ini yang paling sederhana:

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

7
Layak dikualifikasikan bahwa ini hanya berfungsi dengan baik dengan tipe integer. Jika Anda menggunakan string, terutama yang disediakan pengguna (seperti kriteria pencarian) maka Anda harus keluar dari string, jika tidak, Anda bisa mendapatkan hasil yang aneh jika karakter suka /, +atau &muncul dalam string.
Malvineous

Menggunakan objek Permintaan dapat membantu, terutama jika Anda ingin menggunakan fungsi untuk membangun permintaan dan kemudian menyerahkannya ke panggilan fetch (), tapi saya tidak berpikir menggunakannya adalah "sangat jelas". Juga, url tidak boleh ditentukan dalam objek literal opsi konfigurasi; itu harus diteruskan secara terpisah sebagai parameter pertama ke konstruktor Permintaan ( developer.mozilla.org/en-US/docs/Web/API/Request/Request ).
Gen1-1

3

Templat literal juga merupakan opsi yang valid di sini, dan memberikan beberapa manfaat.

Anda dapat memasukkan string mentah, angka, nilai boolean, dll:

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

Anda dapat memasukkan variabel:

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

Anda dapat memasukkan logika dan fungsi:

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

Sejauh menyusun data string kueri yang lebih besar, saya suka menggunakan array yang digabungkan ke string. Saya merasa lebih mudah dipahami daripada beberapa metode lain:

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

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

9
Anda harus sangat berhati-hati dengan metode ini karena tidak URL-melarikan diri dari string terlebih dahulu. Jadi jika Anda mendapatkan variabel yang berisi karakter suka +atau &tidak akan berfungsi seperti yang diharapkan dan Anda akan berakhir dengan parameter dan nilai yang berbeda dengan apa yang Anda pikirkan.
Malvineous

-1

Hanya bekerja dengan fetchModule Nativescript dan menemukan solusi saya sendiri menggunakan manipulasi string. Tambahkan string kueri sedikit demi sedikit ke url. Berikut adalah contoh di mana kueri diteruskan sebagai objek json (kueri = {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.
}

Saya menguji ini pada beberapa parameter kueri dan itu berfungsi seperti pesona :) Semoga ini bisa membantu seseorang.


1
Ini adalah contoh yang baik mengapa Anda harus menggunakan lib pihak ke-3 - kode Anda mungkin berfungsi dengan baik, tetapi seseorang sudah melakukannya dengan lebih baik
refaelio

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.