Để tạo ra các request HTTP, chúng ta sẽ sử dụng Fetch API. API này cung cấp một phương thức có tên là fetch.

Info

Fetch API là một Browser API nên hiện tại sẽ không chạy được bằng NodeJS.

Đồng thời, Fetch có thể không được hỗ trợ ở tất cả các trình duyệt trừ khi chúng ta cài đặt các package hỗ trợ.

Update: NodeJS phiên bản v16.15.0 đã có thể sử dụng Fetch API.

Using the Fetch API

Phương thức fetch có đối số là một URL của API. Phương thức này trả về một đối tượng thuộc lớp đối tượng Promise.

Dưới đây là một ví dụ sử dụng fetch:

fetch("https://nekos.best/api/v2/neko")
  .then((response) => response.json())
  .then((data) => console.log(data))
  .catch((error) => console.log(error))

Sau khi có đối tượng trả về thì dùng phương thức then để trích xuất ra dữ liệu JSON thông qua phương thức json() gọi từ đối tượng response.

Phương thức json() cũng trả về một promise, và vì thế ta gọi phương thức then thứ hai để lấy giá trị trả về của promise này.

Supplying Request Options

Ngoài ra, fetch còn có đối số thứ hai có tên là options, là một object bao gồm nhiều field. Một số field quan trọng:

  • body: request body, có thể là FormData (cho form data), URLSearchParams (cho x-www-form-urlencoded), string object, …
  • cache: thiết lập HTTP header Cache-Control. Bao gồm các giá trị sau: defaultno-storereloadno-cacheforce-cache, and only-if-cached.
  • credentials: kiểm soát cách browser xử lý credentials (cookie, HTTP authentication entries và TLS client certificates). Các giá trị có thể sử dụng:
    • omit: không bao gồm trong request và ignore các credential trong response (chẳng hạn như header Set-Cookie).
    • same-origin: thêm credentials đối với các request có cùng origin (cùng scheme, domain và port). Có sử dụng credentials trong response. Đây là giá trị mặc định.
    • include: thêm credentials đối với các request same-origin và cả cross-origin. Có sử dụng credentials trong response.
  • headers: là một object bao gồm các HTTP header cần thêm vào request. Có một số header trong request không được phép dùng: Forbidden header name. Đối với response thì Set-Cookie không được phép dùng.
  • method: phương thức HTTP.
  • mode: thiết lập chế độ của request, bao gồm các giá trị: corsno-cors và same-origin. Field này sẽ thiết lập giá trị cho header Sec-Fetch-Mode1.
  • redirect: xử lý khi response redirect. Thường sử dụng giá trị follow.
  • referrer: thiết lập header Referer trong request.
  • referrerPolicy: quy định chính sách của header Referer2. Bao gồm các giá trị: no-referrerno-referrer-when-downgradesame-originoriginstrict-originorigin-when-cross-originstrict-origin-when-cross-origin và unsafe-url. Với no-referrer sẽ bỏ header Referer ra khỏi request.

Ví dụ sử dụng các option trên để thay đổi username của người dùng:

fetch("http://localhost:3030/profile", {
  method: "POST",
  cache: "no-store",
  mode: "no-cors",
  credentials: "include",
  redirect: "follow",
  referrerPolicy: "no-referrer",
  headers: {
    "Content-Type": "application/x-www-form-urlencoded",
  },
  body: new URLSearchParams({
    username: "CSRF",
  }),
})

Aborting a Fetch

Chúng ta có thể hủy bỏ một request được gửi bởi fetch khi nó chưa hoàn thành bằng cách dùng AbortControllerAbortSignal như sau:

const controller = new AbortController()
const signal = controller.signal
const url = "video.mp4"
 
const downloadBtn = document.querySelector("#download")
const abortBtn = document.querySelector("#abort")
 
downloadBtn.addEventListener("click", async () => {
  try {
    const response = await fetch(url, { signal })
    console.log("Download complete", response)
  } catch (error) {
    console.error(`Download error: ${error.message}`)
  }
})
 
abortBtn.addEventListener("click", () => {
  controller.abort()
  console.log("Download aborted")
})

Trong ví dụ trên, khi nút abort được bấm thì hàm controller.abort() sẽ được gọi. Hàm này sẽ hủy bỏ request đang được gửi bởi hàm fetch.

Resources

Footnotes

  1. xem thêm https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-Fetch-Mode

  2. xem thêm https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy