iT邦幫忙

2023 iThome 鐵人賽

DAY 29
0
自我挑戰組

重新複習JavaScript系列 第 29

[Day -29] fetch 與 axios

  • 分享至 

  • xImage
  •  

昨天我們認識了AJAX,但並沒有XMLHttpRequest ,最根本的原因在於:我不會,而且現在應該很少人用這個來請求了吧?現在大家不是都用fetchaxios…因此我就沒有介紹了。

那這篇就是要來介紹現在大家最常使用的fetch 以及axios

Fetch()

fetch()是一個全域的方法,包含了需要 fetch 的網址和對應的屬性設定 ( 例如 method、headers、mode、body...等,最基本的寫法屬性不一定要填 ),執行之後會送出 Request。

fetch基本語法:

let promise = fetch(url, [options])

裡面幾個參數的介紹:

  • url:一定要填,要訪問的網址。
  • options:是一個可選的参數,例如method、header。

如果只有放url 這個參數,沒有放[options],就會預設這個請求的HTTP請求方法是GET。

其餘options可以觀看MDN

Fetch()的語法結構與Promise非常相似,同樣是用thencatch方法來處理成功和失敗的結果,如果送出去的請求得到回應就會回傳帶有 Response 的 Promise 物件(狀態是fulfilled),使用 then 將回傳值傳遞下去:

fetch("http://example.com/movies.json")
  .then(function (response) {
    return response.json();
  })
  .then(function (myJson) {
    console.log(myJson);
  })
	.catch(function (error) {
    console.log(error);
  });

Fetch 的 Request 屬性

介紹一些常用的 Request屬性,其餘部分大家可以到 MDN 上查看:

屬性 設定值
url 第一個參數,一定要填的項目,代表需要 fetch 對象的網址
method GET、POST、PUT、DELETE、HEAD ( 預設 GET )
headers 要求相關的 Headers 物件 ( 預設 {} )
mode cors、no-cors、same-origin、navigate ( 預設 cors )
redirect follow、error、manual ( 預設 manual )
cache default、no-store、reload、no-cache、force-cache ( 預設 default )
body 要加到要求中的內容 ( 如果 method 為 GET 或 HEAD 則不設定 )

Fetch 的 Response 屬性

介紹一些常用的 Respons 屬性,其餘部分大家可以到 MDN 上查看:

屬性 設定值
headers 包含與 response 相關的 Headers 物件
ok 成功回傳 true,不成功回傳 false
status 狀態代碼,成功為 200
statusText 狀態文字,成功為 ok
type response 的類型,例如 basic、cors...等
url response 的 url

Fetch 的 Response 方法

介紹一些常用的 Respons 方法,其餘部分大家可以到 MDN 上查看:

方法 設定值
json() 返回 Promise,resolves 是 JSON 物件
text() 返回 Promise,resolves 是 text string
formData() 返回 Promise,resolves 是 formData ( 表單資料對應的的 Key 或 Value )
clone() 建立 Response 的複製物件
error() 返回 Response 的錯誤物件

注意,只能使用一種方法來取得資料。例如我用了.json()的方法後,不能再用另一種方法來取得資料,因為該資料已經被處理過了。

簡單的案例

看了這麼多文字跟表格,我們來實際操作一次吧。

以下範例的請求都會從 httpbin.org 這個網站裡挑選,它提供了各種不同的請求方式,在練習時是個很棒的工具。

  • Get 用法

    先來看一下code:

    fetch('https://httpbin.org/get')
        .then((response) => {
            console.log(response)
            return response.json()
            //return response.text()
        }).then((myJson) => {
            console.log(myJson)
        })
    

    我們剛剛學到過,當fetch()裡面只有 url 這個參數時,它的HTTP請求方法是GET。

    當 fetch() 接受**'https://httpbin.org/get'** 這個網址時,表示要請求這個URL。

    當請求通過後我們會得到一個Promise,以及此次請求的相關資訊:

    讓我們看一下Response裡面有什麼:

    裡面有請求的 url 和用來判斷請求是否成功的 status 狀態,以及我們剛剛前面有看到過的屬性。

    那我們用console.log(myJson) 的內容又會是怎樣呢:

    這邊有件事情要提醒一下,在 response 中有兩個內建函式可以用來得到請求回傳的資料。

    一個是我們目前使用的return response.json() ,他能夠將回傳的資料以物件的方式傳給第二個 then 接收。

    但當今天我們使用return response.text() ,當回傳的資料無法轉換為物件時,則會將請求資料以字串方式取出。

    就會像這樣:

    我們可以看到前面回傳的都是一樣的,但是在第二個then()之後,console出來的卻都是字串了。

  • Post 用法

    一樣先看一下code:

    fetch('https://httpbin.org/post', {
        method: 'POST',
        body: JSON.stringify(
            {
                name: 'GQSM',
                age: 25
            }
        )
    }).then((response) => {
        return response.json()
    }).then((myJson)=>{
        console.log(myJson)
    })
    

    我們可以看到使用 POST 請求時需另外在 method 屬性內指定 POST 方式,且多了 body 屬性指定要送出的資料。

    另外我們還可以看到這裡:JSON.stringify()

    為什麼要先轉換成字串型態呢?這是因為:

    • HTTP POST 請求的 body 須為字符串
      根據 HTTP 協議,POST 請求的 body 可以包含不同類型的數據,如純文本、XML、JSON 等。然而,無論您要傳遞什麼類型的數據,它都必須是字符串。
      這是因為 HTTP 協議在傳輸數據時要求它們以純文本字符串的形式進行傳遞。

    我們可以來看一下沒有轉成字串會發生什麼事:

    注意到了嗎?在data那欄出現的是 [object Object] ,這也導致我們的請求在 server 端則是沒有辦法接收到正確的內容。

請求失敗

在 Fetch 中,請求失敗時不會有 error 可以直接捕捉,而是要以 response  的 status 的屬性值判斷,當 status 的值不等於 200 時,將在 .then 中使用 throw 創建一個錯誤,並由  .catch  接收錯誤內容處理

以上就是簡單Fetch()介紹,接下來換axios

Axios

什麼是axios ?

它是一個基於 Promise 的 HTTP 客戶端庫,主要用於瀏覽器和 Node.js 環境中進行 HTTP 請求。它簡化發送 HTTP 請求、處理回應和處理異常。

以下是 Axios 的一些主要特點和功能:

  1. 簡單的 API:Axios 提供了一個簡單、一致的 API,使您能夠輕鬆發送各種類型的 HTTP 請求,包括 GET、POST、PUT、DELETE 等。
  2. Promise 基礎:Axios 基於 JavaScript Promises,這使得處理異步請求和回應更容易和具可讀性。
  3. 自動 JSON 轉換:Axios 在發送請求時自動將 JavaScript 對象轉換為 JSON 字符串(當您傳遞對象作為請求主體時),並在接收回應時自動將 JSON 字符串轉換為 JavaScript 對象。
  4. 處理錯誤:Axios 具有強大的錯誤處理功能,它可以捕獲並處理各種類型的錯誤,例如網絡錯誤、HTTP 錯誤狀態碼和超時。
  5. 取消請求:Axios 允許您取消未完成的請求,這對於處理用戶取消操作或避免冗餘請求非常有用。

基本語法

axios(url[,config])

axios回傳的物件是Promise(fulfilled狀態),所以我們一樣可以用.then.catch去處理成功和失敗結果。

  • Get 用法

    axios.get('https://httpbin.org/post')
      .then(response => {
        // 成功的回應
        console.log('成功:', response.data);
      })
      .catch(error => {
        // 失敗或錯誤處理
        console.error('錯誤:', error);
      });
    
  • Post 用法

    axios.post('https://httpbin.org/post', {
      title: '標題',
      body: '內容',
      userId: 1
    })
      .then(response => {
        // 成功的回應
        console.log('成功:', response.data);
      })
      .catch(error => {
        // 失敗或錯誤處理
        console.error('錯誤:', error);
      });
    
  • config物件 用法

    我們還可以通過傳遞一個 object 來自定義請求。

    // 定義請求配置
    const config = {
      method: 'POST', // 請求方法
      url: 'https://httpbin.org/post', // 請求的URL
      headers: {
        'Content-Type': 'application/json', // 請求標頭
      },
      data: { // 請求主體的數據
        title: '標題',
        body: '內容',
        userId: 1
      },
    };
    
    // 發送請求
    axios(config)
      .then(response => {
        // 成功的回應
        console.log('成功:', response.data);
      })
      .catch(error => {
        // 失敗或錯誤處理
        console.error('錯誤:', error);
      });
    

    使用 config 的方式使您能夠更靈活地設置和自定義每個請求。

**.create來預設axios裏的config物件

剛剛我們有介紹使用**config** 的方式來傳遞請求,axios有一個很方便的方法讓我們預設config。

const instance = axios.create({
  baseURL: 'https://httpbin.org/post', // 設定基本 URL
  timeout: 5000, // 設定請求超時時間,超過時間請求就會被中斷
  headers: {
    'Content-Type': 'application/json', // 預設請求標頭
  },
});

// 使用預設配置的 GET 請求
instance.get('/posts/1')
  .then(response => {
    // 成功的回應
    console.log('成功:', response.data);
  })
  .catch(error => {
    // 失敗或錯誤處理
    console.error('錯誤:', error);
  });

// 使用預設配置的 POST 請求
instance.post('/posts', {
  title: '標題',
  body: '內容',
  userId: 1
})
  .then(response => {
    // 成功的回應
    console.log('成功:', response.data);
  })
  .catch(error => {
    // 失敗或錯誤處理
    console.error('錯誤:', error);
  });

利用.create方法,我們就少寫一些重複的東西。這是一個最適合懶人的做法XD


我承認我有點懶惰了axios確實找比較少的資料,原諒我吧!!!
明天就是最後一天了,這段旅程真的要結束了!!!

參考資料:

https://eyesofkids.gitbooks.io/javascript-start-from-es6/content/part4/ajax_fetch.html

https://www.meticulous.ai/blog/fetch-vs-axios

https://medium.com/enjoy-life-enjoy-coding/jacascript-fetch-讓-es6-擁有一對翅膀-基礎教學-2f98efe55ba4


上一篇
[Day -28] AJAX與溝通協定
下一篇
[Day -30] 旅程的終點?不這只是起點!
系列文
重新複習JavaScript30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言