Pengantar fetch()

fetch() API mendarat di objek jendela dan ingin mengganti XHR

XMLHttpRequest selama ini

fetch() memungkinkan Anda membuat permintaan jaringan yang mirip dengan XMLHttpRequest (XHR). Perbedaan utamanya adalah Fetch API menggunakan Promise, yang memungkinkan API yang lebih sederhana dan rapi, menghindari callback, dan harus mengingat API kompleks XMLHttpRequest.

Dukungan Browser

  • 42
  • 14
  • 39
  • 10.1

Sumber

Fetch API telah tersedia dalam cakupan global Pekerja Layanan sejak Chrome 40, tetapi akan diaktifkan dalam cakupan jendela di Chrome 42. Ada juga polyfill dari GitHub yang dapat Anda gunakan saat ini.

Jika Anda belum pernah menggunakan Promise, lihat Pengantar Promise JavaScript.

Permintaan Pengambilan Dasar

Mari kita mulai dengan membandingkan contoh sederhana yang diterapkan dengan XMLHttpRequest, lalu dengan fetch. Kita hanya ingin meminta URL, mendapatkan respons, dan menguraikannya sebagai JSON.

XMLHttpRequest

XMLHttpRequest memerlukan dua pemroses yang ditetapkan untuk menangani kasus keberhasilan dan error, serta panggilan ke open() dan send(). Contoh dari dokumen MDN.

function reqListener() {
    var data = JSON.parse(this.responseText);
    console.log(data);
}

function reqError(err) {
    console.log('Fetch Error :-S', err);
}

var oReq = new XMLHttpRequest();
oReq.onload = reqListener;
oReq.onerror = reqError;
oReq.open('get', './api/some.json', true);
oReq.send();

Ambil

Permintaan pengambilan kita terlihat sedikit seperti ini:

fetch('./api/some.json')
    .then(
    function(response) {
        if (response.status !== 200) {
        console.log('Looks like there was a problem. Status Code: ' +
            response.status);
        return;
        }

        // Examine the text in the response
        response.json().then(function(data) {
        console.log(data);
        });
    }
    )
    .catch(function(err) {
    console.log('Fetch Error :-S', err);
    });

Kita mulai dengan memeriksa apakah status respons adalah 200 sebelum mengurai respons sebagai JSON.

Respons permintaan fetch() adalah objek Stream, yang berarti bahwa saat kita memanggil metode json(), Promise akan ditampilkan karena pembacaan aliran data akan terjadi secara asinkron.

Metadata Respons

Pada contoh sebelumnya, kita melihat status objek Response serta cara mengurai respons sebagai JSON. Metadata lain yang mungkin ingin kita akses, seperti {i>header<i}, digambarkan di bawah ini.

fetch('users.json').then(function(response) {
    console.log(response.headers.get('Content-Type'));
    console.log(response.headers.get('Date'));

    console.log(response.status);
    console.log(response.statusText);
    console.log(response.type);
    console.log(response.url);
});

Jenis Respons

Saat kita membuat permintaan pengambilan, respons akan diberi response.type "basic", "cors" atau "opaque". types ini menunjukkan asal resource dan dapat digunakan untuk menunjukkan cara memperlakukan objek respons.

Saat permintaan dibuat untuk resource pada asal yang sama, respons akan memiliki jenis basic dan tidak ada batasan pada apa yang dapat Anda lihat dari respons.

Jika permintaan dibuat untuk resource di asal lain yang menampilkan header COR, jenisnya adalah cors. Respons cors dan basic hampir identik, hanya saja respons cors membatasi header yang dapat Anda lihat ke Cache-Control, Content-Language, Content-Type, Expires, Last-Modified, dan Pragma.

Respons opaque ditujukan untuk permintaan yang dibuat untuk resource dari origin lain yang tidak menampilkan header CORS. Dengan respons buram, kita tidak akan dapat membaca data yang ditampilkan atau melihat status permintaan, yang berarti kita tidak dapat memeriksa apakah permintaan berhasil atau tidak.

Anda dapat menentukan mode untuk permintaan pengambilan sehingga hanya permintaan tertentu yang akan diselesaikan. Mode yang dapat Anda tetapkan adalah sebagai berikut:

  • same-origin hanya berhasil untuk permintaan aset dari asal yang sama, semua permintaan lainnya akan ditolak.
  • cors akan mengizinkan permintaan untuk aset pada origin yang sama dan origin lainnya yang menampilkan header COR yang sesuai.
  • cors-with-forced-preflight akan selalu melakukan pemeriksaan preflight sebelum membuat permintaan yang sebenarnya.
  • no-cors dimaksudkan untuk membuat permintaan ke origin lain yang tidak memiliki header CORS dan menghasilkan respons opaque, tetapi seperti yang telah dinyatakan, hal ini tidak dapat dilakukan dalam cakupan global jendela saat ini.

Untuk menentukan mode, tambahkan objek opsi sebagai parameter kedua dalam permintaan fetch dan tentukan mode dalam objek tersebut:

fetch('http://some-site.com/cors-enabled/some.json', {mode: 'cors'})
    .then(function(response) {
    return response.text();
    })
    .then(function(text) {
    console.log('Request successful', text);
    })
    .catch(function(error) {
    log('Request failed', error)
    });

Perantaian Promise

Salah satu fitur hebat dari promise adalah kemampuan untuk menyatukannya. Untuk pengambilan, ini memungkinkan Anda berbagi logika di seluruh permintaan pengambilan.

Jika menggunakan JSON API, Anda harus memeriksa status dan mengurai JSON untuk setiap respons. Anda dapat menyederhanakan kode dengan menentukan status dan JSON yang mengurai dalam fungsi terpisah yang menampilkan promise, sehingga Anda hanya perlu memikirkan penanganan data akhir dan kasus error.

function status(response) {
    if (response.status >= 200 && response.status < 300) {
    return Promise.resolve(response)
    } else {
    return Promise.reject(new Error(response.statusText))
    }
}

function json(response) {
    return response.json()
}

fetch('users.json')
    .then(status)
    .then(json)
    .then(function(data) {
    console.log('Request succeeded with JSON response', data);
    }).catch(function(error) {
    console.log('Request failed', error);
    });

Kami menentukan fungsi status yang memeriksa response.status dan menampilkan hasil Promise.resolve() atau Promise.reject(), yang menampilkan Promise yang telah diselesaikan atau ditolak. Ini adalah metode pertama yang dipanggil dalam rantai fetch(). Jika berhasil, kita akan memanggil metode json() yang sekali lagi menampilkan Promise dari panggilan response.json(). Setelah itu, kita memiliki objek JSON yang diuraikan. Jika penguraian gagal, Promise akan ditolak dan pernyataan catch akan dijalankan.

Hebatnya, Anda dapat membagikan logika di semua permintaan pengambilan, sehingga kode lebih mudah dikelola, dibaca, dan diuji.

Permintaan POST

Tidak jarang aplikasi web ingin memanggil API dengan metode POST dan memberikan beberapa parameter dalam isi permintaan.

Untuk melakukannya, kita dapat menetapkan parameter method dan body dalam opsi fetch().

fetch(url, {
    method: 'post',
    headers: {
        "Content-type": "application/x-www-form-urlencoded; charset=UTF-8"
    },
    body: 'foo=bar&lorem=ipsum'
    })
    .then(json)
    .then(function (data) {
    console.log('Request succeeded with JSON response', data);
    })
    .catch(function (error) {
    console.log('Request failed', error);
    });

Mengirim Kredensial dengan Permintaan Pengambilan

Jika ingin membuat permintaan pengambilan dengan kredensial seperti cookie, Anda harus menetapkan credentials permintaan ke "include".

fetch(url, {
    credentials: 'include'
})

FAQ

Bagaimana cara membatalkan permintaan fetch()?

Untuk saat ini, tidak ada cara untuk membatalkan pengambilan, tetapi hal ini sedang dibahas di GitHub. H/T @jaffathecake untuk link ini.

Apakah ada polyfill?

GitHub memiliki polyfill untuk pengambilan. H/T @Nexii untuk menunjukkan hal ini.

Mengapa "no-cors" didukung di pekerja layanan tetapi tidak di jendela?

Hal ini dilakukan karena masalah keamanan. Anda dapat mempelajari lebih lanjut di sini.