[angular]調用API使用Cookie

在用angular2調用後臺接口的時候,遇到了兩個問題1、請求頭沒有cookies;2、對兩次請求,node後端都開了一個新的線程。對於這兩個問題,其實我認爲解決了請求頭cookie的問題,後面的問題自然解決。對於cookie有什麼作用,爲什麼要有這個cookie,看下圖前後端請求模式。

clipboard.png

clipboard.png

clipboard.png

不難看出,這個cookie是獲取session會話中信息的憑證,只有向後臺傳送匹配的cookie,才能得到相應的信息,否則將創建新的session。

到這裏,來看下XMLHttpRequest.withCredentials這個屬性,度娘解釋如下

XMLHttpRequest.withCredentials  屬性是一個Boolean類型,它指示了是否該使用類似cookies,authorization headers(頭部授權)或者TLS客戶端證書這一類資格證書來創建一個跨站點訪問控制(cross-site Access-Control)請求。在同一個站點下使用withCredentials屬性是無效的。

此外,這個指示也會被用做響應中cookies 被忽視的標示。默認值是false。

如果在發送來自其他域的XMLHttpRequest請求之前,未設置withCredentials 爲true,那麼就不能爲它自己的域設置cookie值。而通過設置withCredentials 爲true獲得的第三方cookies,將會依舊享受同源策略,因此不能被通過document.cookie或者從頭部相應請求的腳本等訪問。

angular2中http顯然也是基於xml的請求,必定有這個屬性。再看下http接口的請求接口說明。默認情況下,一般瀏覽器的CORS跨域請求都是不會發送cookie等認證信息到服務端的,除非指定了xhr.withCredentials = true,但是隻有客戶端單方面的設置了這個值還不行,服務端也需要同意纔可以,所以服務端也需要設置好返回頭Access-Control-Allow-Credentials: true;還有一點要注意的,返回頭Access-Control-Allow-Origin的值不能爲星號,必須是指定的域,否則cookie等認證信息也是發送不了。

Interface Details

url : string
method : string|RequestMethod
search : string|URLSearchParams|{[key: string]: any | any[]}
params : string|URLSearchParams|{[key: string]: any | any[]}
headers : Headers
body : any
withCredentials : boolean
responseType : ResponseContentType

問題找到了,就是這貨!再修改下請求代碼

clipboard.png

再來看下請求頭信息

clipboard.png

clipboard.png

顯然,請求頭都已經被加上了cookie,而且這個cookie都是匹配的,看似沒什麼問題,但是再看看請求接口的response,沒有任何信息,但後臺明顯有返回信息,而且這個response並非每次都不返回任何信息,存在偶然性。

 

clipboard.png

到這裏,明顯就出現了另一個問題,就是跨域,看看瀏覽器的console信息就知道了

XMLHttpRequest cannot load http://neil.com:8090/api/send. The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin 'http://localhost:4200' is therefore not allowed access. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

到這裏,問題清晰了,只要解決跨域問題,整個流程就跑通。網上也有很多辦法處理跨域,但如果不想用jsonp呢,那隻能從服務器上動刀子。查了些資料,最靠普的無非在服務端加上request頭部設置

//設置跨域訪問
app.all('*', function (req, res, next) {
    res.header("Access-Control-Allow-Origin", "http://neil.com:4200");   //設置跨域訪問
    res.header('Access-Control-Allow-Credentials', 'true');
    res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
    res.header('Access-Control-Allow-Headers', 'Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With');
    res.header("Content-Type", "application/x-www-form-urlencoded");
    next();
});

這裏說明下,‘Access-Control-Allow-Origin’必須設置請求側的域名,不然無法跨域,不能解決問題。

clipboard.png

現在,問題已經全部處理。

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