跨域請求的解決方案和使用axios讓請求頭部攜帶含有登錄標記的cookie的方法

跨域請求的解決方案和使用axios讓請求頭部攜帶含有登錄標記的cookie的方法

跨域與同源

當一個請求url的協議、域名、端口三者之間任意一個與當前頁面url不同即爲跨域;相反地,所謂同源就是兩個頁面具有相同的協議,主機和端口號。若一個項目的前後端是分離的,那麼前後端部署時就可能部署到不同的域名下或相同域名下的不同端口,那麼這時的前後端是跨域的;若前後端合併在一起並部署在同域名下的同端口,那麼兩者同源。

跨域請求的解決方案

例如,我使用django框架搭建了API請求後端,並部署在一臺雲服務器上,而同時,我在本地電腦上用vue開發了一個前端頁面,現在我想在前端頁面上發起post請求去請求服務器上的API,由於前後端發生了跨域,這時前端的請求是無法獲取後端返回的數據的。

在django中的解決方法是:
安裝django-cors-headers

pip install django-cors-headers

然後在setting.py中註冊該應用,如下:

INSTALLED_APPS = (
...
'corsheaders',   
...
)

然後在中間件中註冊:

MIDDLEWARE_CLASSES
= (
...   
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',   
...
)

注意註冊的順序!!!,不能把該中間件註冊太靠後,不然不起作用,我的順序如下:
在這裏插入圖片描述

然後再setting.py末尾增加以下內容:

CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_WHITELIST = ()
CORS_ALLOW_HEADERS = (
    "*"
)

其中要注意CORS_ALLOW_CREDENTIALS = True這一項,這一項指是否允許前端的請求頭部攜帶驗證的cookie信息,具體用法後面會提及。

完成上述配置,就可以在本地電腦上訪問雲服務器上的api。

跨域下的登錄保持

例如,在django後端的登錄API中,使用的session來保存用戶的登錄信息,那麼前端成功訪問了登錄的API後,會在響應頭部的set-cookie中發現後端設置的sessionid,如下圖:
在這裏插入圖片描述

正常來說,當我們登錄後,若我們進行登陸後的操作,前端必須將這個sessionid放在請求頭部裏,以讓後端能辨別出發出請求的是剛剛登錄的用戶,這樣整個系統才能正常運行。 但是在跨域的情況下,出於安全性的考慮,由於CORS的限制,爲了防止出現跨域攻擊,前端一般是無法直接獲取Set-Cookie裏的值,爲了實現登錄的保持,我們需要一些跨域下的解決方案。

由於js不允許手動設置請求頭的cookie,且我們很難獲取Set-Cookie裏的值,那麼想要通過獲取sessionid 並手動設置請求頭的方法行不通。

Axios解決方法是:
在vue項目中安裝了axios的情況下,在main.js中增加這樣一條設置:

axios.defaults.withCredentials = true;

相應地,在django後端框架的setting.py中,設置類似的屬性:

CORS_ALLOW_CREDENTIALS = True

這樣的話,當我們登錄後,再想要進行其它API的請求是,axios會自動幫我們把登陸時相應頭裏的Set-Cookie的值添加到請求頭,如下圖:
在這裏插入圖片描述

這樣便能成功將sessionid傳給後端並保持登錄狀態。

注意!經過測試,在跨域情況下,上述保持登錄的解決方法,適用於前後端部署在相同域名下的不同端口的情況,若前後端部署在不同域名下,還是無法通過上述方法保持登錄。

發佈了62 篇原創文章 · 獲贊 12 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章