iT邦幫忙

2022 iThome 鐵人賽

DAY 21
0
Modern Web

小白大戰基礎網頁開發系列 第 21

D21 - More Fetch and AJAX

  • 分享至 

  • xImage
  •  

還記得昨天的淺談 fetch 嗎? 有了基本的 fetch 認知後, 今天我們要來看更多關於 fetch 的細節與應用, 還有 AJAX 的介紹。

回顧 fetch code 的架構:

    const BASE_URL = ""; // 可能同時會有多個 URL 
    
    // Step 1. 寫個 function 從 URL "fetch" 抓取資料
    function makeRequest() {
      let url = BASE_URL + "?query0=value0"; // 有些需求(requests)需要多個參數, 而有些則不需要
      fetch(url)
        .then(statusCheck)
        //.then(resp => resp.json()) 
        //.then(resp => resp.text()) 
        .then(processData)
        .catch(handleError); // 定義一個使用者友善的錯誤訊息 (error-message) function 
    }
    // Step 2: 應用一個函數來處理數據, 通常會把它拆解成多個函式
    function processData(responseData) {
      // 在這可以對 responseData 做些處理!比如, build DOM, display messages, etc.
    }
    // Step 3. 包含 statusCheck 函式
    async function statusCheck(res) {
      if (!res.ok) {
        throw new Error(await res.text());
      }
      return res;
    }

CORS

CORS: Cross-Origin Resource Sharing (跨來源資源共用)

網站資源: 當使用者打開一個網頁後, 正常來說會看到瀏覽器從不同來源處下載的豐富網頁內容。內容包括不同來源的 code, 圖片或是影片, 而這些 code, 圖片, 影片 即是所謂的網站 資源 (resource)

  • 瀏覽器實施安全措施,限制一個站點訪問/存取另一個站點的資源,除非有明確給予許可。當目前站點請求一個不是目前文件來源的資源時, 例如來自於不同網域(domain)、通訊協定(protocol)或通訊埠(port ), 就會建立一個 跨來源 HTTP 請求(cross-origin HTTP request )
  • Fetch 是遵守 同源政策 (same-origin policy) 的, 同源的資源是允許互相存取的, 而跨來源資源是需要在特定情況下才允許被存取的, 主要目的是為了防範駭客的攻擊。
  • 不過你在網際網路上遇到的許多 API 會比 CORS 更加地鎖定。

AJAX

為什麼 AJAX 有用?

網頁充滿了數據 (data), 通常, 網站 要求 來自保存不同類型數據(txt、json、圖像、數據庫等)的服務器的 data。到目前為止,我們對 JS 的了解並沒有為我們提供任何在 JS 程式之外處理數據的方法。這就是 AJAX 的用武之地!

該如何使用 AJAX?

  • fetch (a built-in JavaScript function)
  • 用 Promise 優雅地去控制來自服務器的成功 - success(200)與錯誤 - error(非 200)回應 (response)

Promise 管道線圖

Promises 的鏈接 (chaining) 為我們提供了一個很好的數據流 (data flow),就像管道一樣!

啟動 fetch URL (a fetch of a URL):

  • 一個 fetch call 返回一個 Promise 物件
  • Promise 物件的 .then 方法 (method) 返回一個 Promise 物件
  • 圖上的第一個 .then(statusCheck) 會去檢查回應 (response) 的狀態,以確保服務器以 OK 的狀態回應 (respond)。 第一個 .then 的結果是另一個 Promise 物件, 其回應 (response) 是 Promise 的值。
  • .then(resp => resp.json()) 也返回一個帶有 JavaScript 物件作為值的 Promise 物件
  • .then(processData) 將會對來自服務器的回應 (response) 做一些事情。
  • 如果任何時候噴出錯誤的話, 執行會落在 Promise 鏈接上的 .catch 方法

Remember: 使用 statusCheck !!

    async function statusCheck(res) {
      if (!res.ok) {
        throw new Error(await res.text());
      }
      return res;
    }

發出請求, 然後與 .then/.catch 做鏈接

    function makeRequest() {
      fetch(BASE_URL + "?query=params")
            .then(statusCheck)
            .then(res => res.json())
            //.then(res => res.text())
            .then(processData)
            .catch(handleError);
    }

發出請求,然後使用 async/await

    async function makeRequest() {
      try {
        let res = await fetch(BASE_URL + "?query=params");
            await statusCheck(res);
            res = await res.json();
            //res = await res.text();
            processData(res);
      } catch(err) {
        handleError(err);
      }
    }

上一篇
D20 - 用 Fetch 抓抓抓
下一篇
D22 - 常常讓人搞混的 Synchronous Programming 和 Asynchronous Programming
系列文
小白大戰基礎網頁開發30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言