iT邦幫忙

2021 iThome 鐵人賽

DAY 19
0
Modern Web

前端藏寶圖系列 第 19

初探 AJAX 與 Fetch API

前言

根據維基百科,20世紀的90年代,伺服器處理每一個瀏覽器請求都要重新載入頁面,換句話說,每當網頁上有任何元素更動的時候,頁面都會消失,直到瀏覽器回應後,再重新載入。聽起來是很令人崩潰的使用者體驗

為了解決上述的問題而出現了非同步載入的概念

雖然非同步載入的概念在1995年就有了,但要到 Google 將這項技術廣泛用在自家的應用程式後,AJAX技術才漸漸受到大家的重視


AJAX

MDN: 全名為 Asynchronous JavaScript And XML,是結合了 HTML、CSS、JavaScript、DOM、還有 XMLHttpRequest 物件,以建立更複雜的網頁程式實做。AJAX 允許網頁只更新需要的部分,而無須重新載入整個頁面。另外,AJAX 也能讓你非同步工作,代表程式碼能在網頁試圖重新載入時持續運行
對比同步(synchronously):則是運行的時候封鎖程式碼運作,直到網頁重新載入成功為止

看完上述 MDN 的定義後,對AJAX的了解可以歸納出幾個重點:

  1. 不是單一技術
  2. 當瀏覽器向伺服器請求資源時,網頁畫面不會壞掉

AJAX 如何運作


圖片來源:w3schools

  1. 第一步是網頁產生一個事件,這個事件可以是載入頁面,網頁的按鈕被點擊等等
  2. 以 JavaScript 創建一個 XMLHttpRequest 物件 (簡稱XHR)
  3. XMLHttpRequest 物件向伺服器發送請求
  4. 伺服器處理請求
  5. 伺服器回傳response給網頁
  6. JavaScript 讀取伺服器的回應
  7. 更新畫面內容

在閱讀資料的過程中發現對於 XHR 都是一面倒的說操作上很麻煩,實務上大多採用HTML 5提供的Fetch API或是函式庫axios

既然前輩們都這麼建議了,以下就來學習fetch()語法


fetch 語法

fetch(resource [, init])
  • resource 的部分:會放入一個 url
  • init 的部分:可放入一個物件,在物件中可以對要發送的請求做客製化設定,例如:method,header 等等,如果沒有指定 method,則會發送 GET 請求

網路上有許多開源的API可以拿來練習fetch語法,以下用了New York Times Books

首先,fetch()會回傳一個帶有 Response 物件的 Promise,可以觀察兩個部分:

  1. status – HTTP 狀態碼
  2. ok – 當HTTP狀態碼介於 200-299 會回傳 true

Response 提供許多以 promise 為基礎的方法,以取得不同的資料格式
最常使用的是response.json() ,將回應解析成JSON格式

解析完後可以看到 results 的部分含有66本書資料的陣列

除了response.json()外,還有以下方法可以將資料解析成不同格式:

  • response.blob()
  • response.text()
  • response.arrayBuffer()
  • response.formData()

小練習

以下用了天瓏書局的API做練習,嘗試使用API提供的書籍圖片網址和書名渲染出簡單的畫面:

  • HTML
<section class="bookshelf">
      <!--render books-->
</section>
  • CSS 簡單排版一下
.bookshelf {
      display: flex;
      flex-wrap: wrap;
      max-width: 80%;
      margin: 0 auto;
    }

    .bookcard {
      flex: 1 1 25%;
    }

    .bookcard > div {
      width: 100%;
    }

    img {
      max-width: 80%;
      object-fit: cover;
    }

    p {
      margin: 10px 0 0 0;
      padding: 0 10px;
    }
  • JS 拿資料再產生畫面
fetch("https://bookshelf.goodideas-studio.com/api")
  .then((res) => res.json())
  .then((books) => createBookCard(books.list))
  .catch((err) => console.log(err));

function createBookCard(data) {
  const bookshelf = document.querySelector(".bookshelf");
  const card = data
    .map((book) => {
      return `<div class="bookcard">
      <div>
        <img src="${book.image}" alt="" />
      </div>
      <p class="booktitle">${book.name}</p>
    </div>`;
    })
    .join("");

  bookshelf.innerHTML = card;
}

這次的練習只做了 GET 的請求,之後有機會再來研究如何發送 POST 請求/images/emoticon/emoticon13.gif

參考資料:
AJAX Introduction
wiki
JAVASCRIPT.INFO
MDN


上一篇
Promise 方法
下一篇
async/await 連體嬰
系列文
前端藏寶圖30

尚未有邦友留言

立即登入留言