添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

今天會承接昨天AJAX的課題,了解常用來處理AJAX的語法,Fetch,以及試試用fetch來實作GET、POST請求。

fetch基本語法

Fetch是一個全域 window 物件,用途是送出request。當請求成功,fetch就會回傳一個promise物件(狀態是fulfilled),這物件內會帶有response物件,裏面會放有我們想抓的資料。

fetch語法:

let promise = fetch(url, [options])
  • url是要訪問的網址
  • options是一堆可選的参數,例如method、header

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

    Fetch的語法結構與Promise非常相似,同樣是用thencatch方法來處理成功和失敗的結果:

    fetch( 你想訪問的url,{...一堆参數(可選)} )
        .then((response) => {
            //成功結果處理
        .catch((error) => {
            //錯誤結果處理
    

    當透過fetch語法,從瀏覽器向伺服器發出GET請求後,接下來的流程可分為兩大部分。以下會用https://randomuser.me/api/去做一個簡單示範,這個API會隨機產生一個人的資料。

    階段1: fetch傳回帶有Response物件的Promise物件

    fetch('https://randomuser.me/api/')
        .then((response) => {
            console.log(response); 
        .catch((error) => {
            console.log(`Error: ${error}`);
    

    我們可以從statusok查看HTTP狀態。ok是一個布林值,如果status是200-299,它就是true

    階段2: 從Response物件中抽取我們想抓的資料

    雖然在階段一回傳了Response物件,但這不是我們想抓的資料,即是我們常常說的「回應內容主體(Response body)」,接下來我們需要使用方法來取得它。

    Response有多種方法讓我們取得資料(內容主體),包括我們常常用到的.json()

    response.json():把資料轉成JSON格式 response.text():把資料轉成text格式(變成純字串) response.blob():把資料轉成Blob物件 response.formData():把資料轉成FormData物件 response.arrayBuffer():把資料轉成二進制數組

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

    我們最常用到就是JSON格式資料,以下例子會用.json()的方法取得資料:

    fetch('https://randomuser.me/api/')
        .then((response) => {
            return response.json();
        .then( (response) => {
            console.log(response);
        .catch((error) => {
            console.log(`Error: ${error}`);
    

    最後就取得資料了:

    async/await的寫法原理是一樣的,以下試試用async/await去重寫以上例子:

    let getJSON = async(url) => {
        let response = await fetch(url);
        let JSON = await response.json();
        console.log(JSON)
    getJSON('https://randomuser.me/api/')
    

    Header

    上面曾提及過,在fetch()裏可以有兩個参數,第一個是URL,第二個是一堆参數,例如methodheader等等。當中的header就是Request header,即是請求表頭,它用來描述我們發出的請求,例如是請求URL、請求方法。

    Header這個術語是指表頭,可以分為請求表頭(Request header)與回應表頭(Response header),它們是一堆描述這個請求或回應的資訊。我們可以用dev tool看到這些資訊:

    請求表頭及回應表頭的格式是有規範,否則不能被伺服器或瀏覽器接收。以下例子示範自訂一個請求表頭:

    let response = fetch('https://randomuser.me/api/',{
        headers: {
            Authentication: 'secret'
    

    但基於HTTP的準確與安全性,某些設定是不能被我們定義,只能被瀏覽器定義。

    當我們發出POST請求時,就需要用到fetch裏的第二個参數,當中包括:

  • method (HTTP請求方法)
  • request body (請求主體)
  • 當中的request body,例如可以是:

  • 字串(用JSON.stringify轉成的字串)
  • FormData物件
  • Blob所傳送的二進制資料
  • 以下用六角學院的API作例子,註冊後會得到一個獨立編碼(UUID),這個UUID是用來組成自己的API網址時用的,另外也會提供一個API token(後台登入驗證碼),用來驗證是否有管理員身分,並能夠管理個人專屬的後台。

    這裏會示範如果新增一筆產品資料到伺服器,剛才提及uuid和token是在註冊六角學院的API系統時發給我的,我把它們放在一個個的變數裏,但這裏就不公開了。

    新增一筆產品資料的API文件:

    Body Parameters就是主體参數,要寫在fetch(url,{...}){...}裏。

    以下是完整程式碼:

    const uuid = xxxxx
    const token = xxxxx
    const url = `https://course-ec-api.hexschool.io/api/${uuid}/admin/ec/product`
    let headers = {
        "Content-Type": "application/json",
        "Accept": "application/json",
        "Authorization": `Bearer ${token}`,
    //以下是API文件中提及必寫的主體参數。而以下這個產品資料是六角學院提供的。
    let body = {
        "title": "Abysswalker",
        "category": "T-Shirts",
        "content": "Its wearer, like Artorias himself, can traverse the Abyss.",
        "description": "This official Dark Souls shirt was designed by Nina Matsumoto and printed on soft 100% cotton shirts by Forward. Each one comes with a bonus sticker.",
        "imageUrl": ["https://images.unsplash.com/photo-1529374255404-311a2a4f1fd9?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1349&q=80"]
    fetch(url, {
        method: "POST",
        headers: headers,
        //別忘了把主體参數轉成字串,否則資料會變成[object Object],它無法被成功儲存在後台
        body: JSON.stringify(body)
        .then(response => response.json())
        .then(json => console.log(json));
    

    如果我新增了3次這筆資料,後台就會有3筆資料,我們也可以用"GET"的方法去查詢,六角學院提供了以下的API文件:

    完整程式碼:

    const url = `https://course-ec-api.hexschool.io/api/${uuid}/admin/ec/products`
    let headers = {
        "Content-Type": "application/json",
        "Accept": "application/json",
        "Authorization": `Bearer ${token}`,
    fetch(url, {
        method: "GET",
        headers: headers,
        .then( (response) => response.json())
        .then( (json) => console.log(json));
    

    結果真的會顯示3筆資料:

    雖然之前已經學了Promise語法,學習Fetch時不會太吃力,但認真落手實作時才發覺也有一定的難度,而且當中有些術語,例如Body parametres、Header等等也沒有看懂,所以除了看文章,也真的是需要實作練習一下~

    AJAX 完整解說系列:新增、更新、刪除(POST、PATCH、DELETE)
    JAVASCRIPT.INFO
    JacaScript | Fetch 讓 ES6 擁有一對翅膀-基礎教學
    鐵人賽:ES6 原生 Fetch 遠端資料方法