參考資料:TechBridge 技術共筆部落格-輕鬆理解 Ajax 與跨來源請求
跨域來源資源共用 – API 利過 AJAX 行為接收遠端資料
什麼是 API – Application Programming Interface (應用程式介面)
全名是 Application Programming Interface 中文翻作應用程式介面,其中的介面指的是程式跟程式之間的串接讀取檔案,API 程式也使用這個功能了。
Facebook 登入為例,串接「Facebook 提供的 API」,就等於說是 Facebook 向外提供給大家的一套介面、一套標準,任何想要接入 Facebook 服務的開發者們,都可以遵循著使用規範拿到與取得資料,這個東西就叫做 API。
API 資料文件 (API Documentation)
像是呼叫作業系統或是程式語言的函式庫提供的 Function,而這些 Function 通常都可以在官方文件上查到更詳細的說明。
- 文件內就會寫出使用的 function() 或是對應傳入的參數。
- API 的串接也是一樣,一定要有文件你才知道怎麼串,不然根本串不起來,因為你連要傳什麼參數都不知道。
- 需要有個 Client ID 才能針對像是 API Root 的 URL , https://api.twitch.tv/kraken 等來做 API 的基本操作。
- 如果要找對應的使用方式與傳入參數的用法,像是 Get Top Games 為例 (可在右上方的 Search Docs 輸入快查),就會出現該頁的 Get Top Games 文件。
- 網頁開發時都直接講 API ,主要指的是 Web API,也就是透過網路來傳輸的 API,但也有非 Web API 的開發文件,像是開發作業系統也對應的 API 用法,在本機執行沒透過網路。
- API 文件發送請求 (Request),Twitch 傳回目前最熱門的遊戲列表例子, https://api.twitch.tv/kraken/games/top?<client_id=xxx>。開始時向 Twitch 要資料,更精確的說法是利用 JavaScript 發送 Reuqest 取得資料。
AJAX – Asynchronous JavaScript and XML (非同步)
瀏覽器上面發送 Request 應用技術 Asynchronous 非同步。
非同步指的是執行到某一行的時候,會等這行執行完畢,才執行到下一行,確保執行順序。
非同步的概念:
- 發送 Request 之後(點餐之後),不用等 Response 回來(不用等也還沒做好)。
- 做自己的事走到座位。
- 等 Response 回來之後(等餐點做好之後),將結果送過來(送餐到座位過來),JS 中執行的部份就是 Callback Function。
XMLHttpRequest (XHR):內建於瀏覽器的 JavaScript 物件
無需重新載入整個頁面。這就是所謂的 AJAX (Asynchronous JavaScript and XML) 技術的核心。
1 2 3 4 5 6 7 8 9 10 | var request = new XMLHttpRequest(); request.open('GET', `https://api.twitch.tv/kraken/games/top?client_id=xxx`, true); request.onload = function() { if (request.status >= 200 && request.status < 400) { // Success! console.log(request.responseText); } }; request.send(); |
為什麼現在較少直接使用 XHR?
XHR 是 AJAX 的基石,但直接使用它來處理請求會比較繁瑣,需要手動處理很多細節,例如狀態碼、錯誤處理、請求頭設定等。
現代前端開發中多以 Fetch API 或是 Axios 等第三方 HTTP 客戶端函式庫來處理。
Same-Origin Policy (SOP):瀏覽器內建預設的限制,同源政策
瀏覽器內建的核心安全機制,防止惡意網站從另一個網站竊取敏感資料, JavaScript 程式碼能讀取或修改相同來源 (Origin) 的資源。
一個「來源」由以下三個部分組成:
- 通訊協定 (Protocol/Scheme)
- 主機名稱 (Host/Domain)
- 埠號 (Port)
Cross-Origin Resource Sharing (CORS):跨來源資源共享,HTTP 標準「允許跨來源請求的機制」需伺服器端配置
CORS 是一種允許「例外」發生的機制。當瀏覽器發出跨來源請求時,如果伺服器的回應中包含了正確的 CORS 相關 HTTP 標頭,那麼瀏覽器就會知道該伺服器已明確允許此跨來源請求,進而繞過 SOP 的限制,讓 JavaScript 能夠讀取伺服器的回應。
開啟跨來源 HTTP 請求,Server 必須在 Response 的 Header 裡面加上 Access-Control-Allow-Origin。
瀏覽器收到 Response 之後,檢查 Access-Control-Allow-Origin 裡面的內容,裡面有包含發起 Request 的 Origin 的話,就會允許通過讓程式順利接收到 Response。
Preflight Request (預檢請求):OPTIONS 請求確認之後才才決定 Request 能不能送出
HTTP 請求發送非簡單(non-simple)的跨域請求之前自動發出,其主要目的是為了安全性。確保伺服器明確允許該跨域請求,並了解伺服器是否支援 CORS(跨來源資源共享)協定。
瀏覽器發一個 Request 會處理二個動作,第一個的 Method 是 OPTIONS,而後加了一個 Header 就多了一個 Request,
當 Request 中有自定義的 Header 資訊,例如加上 id 等等要驗証的資料,就會以 非簡單(non-simple) 的請求方式進行,也就會多了 Preflight Request (預檢請求) 的機制,當 Preflight Request 沒過的話, Request 也就不會發送了。
例如發送 DELETE 的 Request 給這個 API,發送出去收到結果的時,會知道 API 沒提供 CORS,因此真 DELETE 請求就不會送出,到這邊就結束了。
用一個 OPTIONS 的請求去確認之後的 Request 能不能送出,這就是 Preflight Request 的目的。