1. 程式人生 > >CORS 前端請求跨域時遇到的一些坑 後臺解決方法

CORS 前端請求跨域時遇到的一些坑 後臺解決方法

最近寫介面和前端vue互動,這樣就需要定義token來驗證,之前的專案都是前後臺不分離,我們都是服務的使用cookie或session。來存取資料。現在前後端分類,那麼token驗證是必不可少的,之前由於跨域問題,我們開始的解決辦法是每次提交資料都攜帶token,這樣就造成每次提交都帶有token,明文傳送容易被別人竊取。
接下來就展示一下解決跨域遇到的坑。

首先遇到的問題就是這個:Access-Control-Allow-Origin的問題

這裡寫圖片描述
跨域遇到的第一個問題就是Access-Control-Allow-Origin的錯誤, Chrome報錯Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.
這裡我們只需要在服務端加上以下程式碼即可(我這裡服務端是php)

header("Access-Control-Allow-Origin: * ");

處理了上述問題後接著請求則又出現報錯:因為我是讓前端將token設定在請求頭中

Access-Control-Allow-Headers的問題

這裡寫圖片描述
以過上面的程式碼已經實現了跨域中的第一步,GET請求一切正常. 可是需要POST請求傳送資料時又出問題了, Chrome報錯Request header field token is not allowed by Access-Control-Allow-Headers in preflight response. 查了下資料,大致意思是請求頭中的token欄位內容沒有在Access-Control-Allow-Headers中被設定為允許.

這個簡單,只需要把這個內容加在Access-Control-Allow-Headers上面就行了,順便也把其它常用的頭都加進去吧. 這裡的token 是我這邊讓前端設定請求頭的 key值

header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Connection, User-Agent, Cookie,token');
OPTIONS請求

以上問題都解決了, 基本上跨域已經搞定, 但仔細看Chrome的Network日誌, 發現有些請求會出現兩次: 第一次是OPTIONS請求方式, 第二次才是正常的POST. 這個OPTIONS是幹嘛的呢?

查了些資料並且測試了下, 發現OPTIONS就是相當於在正式請求介面之前去獲取以下header, 自然就是我們前面所設定的那些header. 如果在這次OPTIONS請求中伺服器有返回正確的header, 這時才會執行後面真正的請求; 否則請求將會被拒絕, 並丟擲錯誤.

即然這次OPTIONS請求僅僅是為了獲取header的, 那麼給它一個空的返回就行了唄, 不需要做任何實際的操作.

/*
 * 判斷 OPTIONS 請求,如果 請求方式為
 * OPTIONS ,輸出頭部直接返回
 */
if(isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] == 'OPTIONS'){
exit();

因為我的專案後臺是用thinkphp5框架寫的,我這邊只需要在如果檔案加入以上程式碼即可

// 准許跨域請求。
header("Access-Control-Allow-Origin: * ");
header("Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE");
header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Connection, User-Agent, Cookie,token');
/**
 * 瀏覽器第一次在處理複雜請求的時候會先發起OPTIONS請求。路由在處理請求的時候會導致PUT請求失敗。
 * 在檢測到option請求的時候就停止繼續執行
 */
if($_SERVER['REQUEST_METHOD'] == 'OPTIONS'){
    exit;
}