1. 程式人生 > >(Ext / Js) ajax 跨域請求傳送兩次解決方案

(Ext / Js) ajax 跨域請求傳送兩次解決方案

    我的專案都是前後端分離,在用ajax請求的時候總是會發送兩次請求,一次OPTIONS(預檢請求),一次正常的POST(OR GET)。通過瀏覽器的開發者除錯工具(network)可以看到options請求不會帶上任何引數,返回null(其實返回值可以在後臺設定)。第二條請求才是我們想要的真正的請求。

    這個問題可以說並不是個問題,瀏覽器發現跨域時,會附加一次options請求。去判斷是否是安全的請求,也就是CORS。整個過程由瀏覽器自動完成,使用者不會感覺得到。但是對於開發者來說,總是不喜歡浪費資源。下面我會介紹如何去減少或者避免OPTIONS請求;

瀏覽器將CORS分為兩中請求:簡單請求(simple request)和複雜請求(not-so-simple-request),兩種處理方式是不一樣的。

一、簡單請求:
簡單請求頭會被加上Origin欄位,用於伺服器判斷是不是允許內的請求域名;
二、複雜請求:
在傳送POST前,傳送一條預檢請求(OPTIONS),請求頭也會帶上Origin欄位;

不管是簡單請求還是複雜請求,我們都一視同仁;

先介紹一些CORS相關的欄位:
1、Access-Control-Allow-Origin
這個欄位是必須的,它的值代表著允許的域名。可以是請求頭的Origin值,也可以是*。

2、Access-Control-Allow-Credentials
這個欄位可選,代表著伺服器是否允許這個域名請求攜帶Cookies,預設是不允許。需要請求帶上Cookies,可以設定為true,也只能設定為true。否則就請刪掉,不要傻乎乎的設定false。
想要拿到cookie,光伺服器允許是不行的,客戶端也要允許,在ajax中配置withCredentials:true。

3、Access-Control-Expose-Headers
可選。cors請求時XMLHttpRequest通過getResponseHeader()只能拿到ache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma這個6個基本的屬性。想要拿到更多的可以再Access-Control-Expose-Headers中指定。

4、Access-Control-Request-Method
必填。這個欄位代表的是伺服器允許的請求方式。

5、Access-Control-Request-Headers
可選。指定瀏覽器CORS請求會額外發送的頭資訊欄位,用逗號分隔。

6、Access-Control-Max-Age
可選。意思是有效期,單位是秒。在有效期內,不會發送另一條options請求。

一下是我在專案上的用法:(Ext6.2.0 + WebApi)
前端:
這裡寫圖片描述

後臺:
這裡寫圖片描述

用Ext的同學可以繼續往下看;

Ext的store請求資料時,以上的配置不會起作用,原因我也不清楚,但是可以配置代理的屬性useDefaultXhrHeader: false;

store就不會用到跨域請求。

–完–