前端串串 API


Posted by Nicolakacha on 2020-09-06

Node.js 和在網頁上呼叫 API 的根本差異

透過 node.js 可以直接呼叫 API,在網頁上是透過瀏覽器,瀏覽器會有一些自己的限制,或是會添加額外的資訊。

傳資料的方式

Form 表單

<form method="POST" action="https://google.com">
    username: <input name="username">
    <input type="submit">
</form>

伺服器回傳什麼 response 都會被瀏覽器跳頁直接渲染出來

透過 JS 交換資料: AJAX

XMLHttpRequest

const request = new XMLHttpRequest()
//非同步接受響應
//load 是加載完成時觸發
request.onload = function() {
    if (request.status >= 200 && request.status < 400) {
        console.log(request.responseText)
    } else {
        console.log("err")
    }
}

//error 是加載失敗時觸發
request.onerror = function() {
    console.log("error")
}

//3個參數
//傳送的請求的型別、請求的URL、是否非同步傳送請求的布林值
request.open("GET", "http://google.com", true)
//send()方法接收一個引數,即要作為請求主體傳送的資料
//呼叫send()方法後,請求被分派到伺服器
request.send()

--------------------------------------------------
// 上面 request.onload = function(){} 的寫法也可改寫成如下

request.addEventListener("load", function() {
    if (request.status >= 200 && request.status < 400) {
        console.log(request.responseText)
    } else {
        console.log("err")
    }
})

傳送請求

open()
request.open("GET", "http://google.com", true)
傳送的請求的型別、請求的 URL、是否非同步傳送請求的布林值

send()
呼叫 send() 方法後,請求被分派到伺服器

接收響應

收到響應後,響應資料會自動填充 XHR 物件的屬性,有以下4個屬性:

  • responseText: 作為響應主體被返回的文字
  • responseXML: 如果響應的內容型別是 text/xmlapplication/xml,這個屬性中將儲存著響應資料的 XML DOM 文件
  • status: 響應的 HTTP 狀態
  • statusText: HTTP狀態的說明

收到響應後,第一步是檢查 status 屬性,以確定響應已經成功返回,狀態碼為 200 為成功。此時, responseText 的內容就緒,而且在內容型別正確的情況下,responseXML 也可以訪問了

此外,狀態碼為 304 表示請求的資源並沒有被修改,可直接使用瀏覽器中快取版本;當然,也意味著響應是有效的

無論內容型別是什麼,響應主體的內容都會儲存到 responseText 中,而對於非 XML 資料而言,responseXML 將為 null

非同步

如果要接收的是非同步響應,就需檢測 XHR 物件的 readyState 屬性,該屬性表示請求/響應過程的當前活動階段。這個屬性可取的值如下:

  • 0 (UNSENT): 未初始化。尚未呼叫 open() 方法
  • 1( OPENED): 啟動。已經呼叫 open() 方法,但尚未呼叫 send() 方法
  • 2 (HEADERS_RECEIVED): 傳送。己經呼叫 send() 方法,且接收到頭資訊
  • 3 (LOADING): 接收。已經接收到部分響應主體資訊
  • 4 (DONE): 完成。已經接收到全部響應資料,而且已經可以在客戶端使用了

只要 readyState 屬性值由一個值變成另一個值,都會觸發一次 readystatechange 事件。可利用這個事件來檢測每次狀態變化後 readyState 的值。通常,我們對 readyState 值為 4 的階段感興趣,因為這時所有資料都已就緒

[注意] 必須在呼叫 open() 之前指定 onreadystatechange 事件處理程式才能確保跨瀏覽器相容性,否則將無法接收 readyState 屬性為0和1的情況

xhr.onreadystatechange = function(){
    if(xhr.readyState === 4){
        if(xhr.status == 200){
            alert(xhr.responseText);
        }
    }
}

XMLHttpRequest 串接 Twitch API 範例

// 注意 callback function 的用法

const APIUrl = 'https://api.twitch.tv/kraken';
const accept = 'application/vnd.twitchtv.v5+json';
const clientId = 'abcde';
function getTopGames(cb) {
  const xhr = new XMLHttpRequest();
  xhr.open('GET', `${APIUrl}/games/top?limit=5`, true);
  xhr.setRequestHeader('Accept', accept);
  xhr.setRequestHeader('Client-ID', clientId);
  xhr.onload = () => {
    if (xhr.status >= 200 && xhr.status < 400) {
      cb(JSON.parse(xhr.response));
    }
  };
  xhr.onerror = () => {
    console.log('error');
  };
  xhr.send();
}

Same origin policy 與跨網域問題

  • 同源政策:相同協定且相同網域下才是同源
  • 跨來源資源共用 (CORS)

server 的 header 加上 Access-Control-Allow-Origin 才可以拿到 response
Ajax 一定受同源政策的管理

JSONP

有些標籤不受同源政策影響,例如 <img><script> 一些情況下,可利用 <script> 不受同源政策的限制,跨域存取 Server 的 JavaScript 資料。

單向傳送資料

以 Email 追蹤為例,放一個很小的圖片在 Email 裡面,Client 一打開信的時候就會發送 request 給 Server,Server 就可以知道有沒有打開


#API #javascript







Related Posts

Python Table Manners - Commitizen: 規格化 commit message

Python Table Manners - Commitizen: 規格化 commit message

[day-7] JS 陣列與物件混合應用

[day-7] JS 陣列與物件混合應用

【單元測試的藝術】Chap 4: 使用模擬物件驗證互動

【單元測試的藝術】Chap 4: 使用模擬物件驗證互動


Comments