中止請求和超時 跨域的HTTP請求 認證方式 JSONP

xiaoxiaoming發表於2018-08-18

中止請求和超時

一個栗子在上傳多少秒以後直接終止請求 // 發起HTTP GEt請求獲取指定URl的內容 // 如果響應成功到達,將會傳入responseText給回撥函式 // 如果響應在timeout毫秒內沒有到達,將會中止這個請求 function timedGetText(url, timeout, callback) { var request = new XMLHttpRequest(); // 建立新請求 var timedout = false; // 是否超時,設定標誌 // 啟動計時器,在timeout毫秒後將終止請求 var timer = setTimeout(() => { // 設定計時器,將在timeout時間之後執行該操作,不同於直接定義,是直接 timedout = true; // 設定標記 request.abort(); // 直接中止請求 }, timeout); // 直接終止請求 request.open('GET', url); request.onreadystatechange = () => { // 定義事件處理程式,如果事件處理完成,直接終止計時器 if (request.readyState !== 4) return; // 如果此時仍然有沒有下載完成的,直接忽視,等待計時器取消 if (timedout) return; // 確定此時仍然沒有超時,如果此時仍然沒有超時,直接取消 cleraTimeout(timer); // 此時已經執行完成任務,取消計時器 if (request.status === 200) // 對回撥函式的處理 callback(request.responseText); // 如果請求成功,將會直接返回成功的文字,並呼叫回撥函式 }; request.send(null); // 直接傳送請求(此請求為非同步操作) }

跨域的HTTP請求

作為同源策略的一部分,XMLHttpRequest物件可以發起HTTP請求,由於同源的影響,導致必須是同源的,

ps script元素不是真正的受到了同源策略的影響,它載入並執行任何來源的指令碼,使用ajax的方式為直接script指令碼完成

或者依舊可以使用cors的方式跨域訪問網站

一些安全問題

如果傳入使用者名稱和密碼,其不能通過跨域傳送(因為這樣可以利用js客戶端的方式,使得分散式破解密碼成為可能) 跨域請求不會包含其他任何的使用者證書 cookie和token 都會被丟棄,如果跨域請求需要這幾種憑證,必須在send方法之前,使用withCredentials

一些認證方式介紹

Singnature 認證

即簽名認證

一次性身份校驗方式,常常用於不同專案之間的api通訊

舉例來自百度翻譯的api介面 https://fanyi-api.baidu.com/api/trans/product/apidoc 上方是百度翻譯的api文件

get請求url如下 http://api.fanyi.baidu.com/api/trans/vip/translate?q=apple&from=en&to=zh&appid=2015063000000001&salt=1435660288&sign=f89f9594663708c1605f3d736d01d2d4

最後一個為簽名,在這裡,這個api使用的是md5的 還有一種加密方式為rsa加密

md5 MD5是輸入不定長度資訊,輸出固定長度128-bits的演算法。經過程式流程,生成四個32位資料,最後聯合起來成為一個128-bits雜湊。基本方式為,求餘、取餘、調整長度、與連結變數進行迴圈運算。得出結果。

目前已經被證實可被破解 還有一些雜湊演算法等其他的加密演算法

繼續舉例 https://help.aliyun.com/document_detail/54274.html 上方的是來自於阿里雲的一個api 只不過使用的是Hmac SHA1演算法加密得到簽名的

HMAC-SHA1 為雜湊運算訊息認證碼,HMAC運用的是雜湊演算法,以一個祕鑰和一個訊息為輸入,生成一個訊息摘要作為輸出。為一種最常用的簽名演算法。用於對一段資訊生成一段簽名的摘要,在GET或者POST請求內

token

token的鑑權流程 https://help.aliyun.com/document_detail/54226.html?spm=a2c4g.11186623.4.1.NKz4kZ 整個流程是先通過使用者賬號體系登入,接著對token認證伺服器傳送申請token的請求,token的有效期自定義,驗證通過後,直接返回給客戶端token,最後驗證token到要訪問的伺服器。即上方為完整的使用者登入過程

ps 使用者登入需要進行鑑權

由於http可被區域網抓包,所以一般使用ssl

後方的token會和後端伺服器進行token的同步 一篇博文 http://www.cnblogs.com/xiekeli/p/5607107.html

還有其他,不在說

舉個例子

下方的栗子實現一個簡單的跨域的js請求,使用的是來自於百度翻譯的api 使用的cors

ps 我根本找不到支援cors的api 貌似是瀏覽器不相容的緣故。。唉。

那就暫時不舉了,總體來說瀏覽器在發現是跨域請求的時候,會自動新增origin頭,如果服務端Access-Control-Allow-Origin 的頭部和origin相同,或者為*號的時候,即可進行同源請求,否則將會拒絕同源請求。

JSONP

可以藉助script傳送HTTP請求,script元素作為一種ajax傳輸機制。 使用script,不會受到同源策略的影響,並且包含JSON編碼資料的響應體會自動解碼

指令碼和安全性 使用script元素進行AJAX傳輸,會執行執行傳送過來的任何js指令碼,這種方式適用於可信的第三方指令碼,如廣告,統計等。

使用script元素呼叫資料時,必須用js函式名和圓括號包裹起來。

使用script元素髮送JSONP請求

一個栗子 ``` // 根據指定的URL傳送一個JSONP請求 function getJSONP(url) { // 為本次請求建立一個唯一的回撥函式名稱,將會拼接成 getJSONP.cb3 // 將會拼接成 ?jsonp=getJSONP.cb3 var cbnum = 'cb' + getJSONP.counter++; // 自增計算器 var cbname = "getJSONP." + cbnum; // 作為JSONP函式的屬性

// 將回撥函式名以表單彪馬的形式新增到url的?後面部分中
// 使用JSONP作為引數名
if (url.indexOf('?') === -1) // 如果url沒有查詢部分
    url += '?jsonp=' + cbname;    // 進行新增引數,拼接成為完整的url
else // 否則
    url += "&jsonp" + cbname;    // 將會作為新的引數進行新增

// 建立script元素用於傳送請求
var script = document.createElement('script');

// 觸發HTTP請求,直接操作DOM建立script節點,讓瀏覽器載入
script.src = url;
document.body.appendChild(script);

} ``` 總體思路是,直接建立script元素,通過新增src屬性,讓script元素代為傳送get請求 檢視響應 此處輸入圖片的描述

相關文章