傳統的cookie方式是利用document.cookie的方式寫進cookie,但是會受到同源策略的影響,在跨域的時候無法傳遞cookie。
當使用XMLHttpRequest對象來發送一個Ajax請求,如果普通Ajax請求,會出現如下錯誤:
服務端需要設置Access-Control-Allow-Origin:* 。
標准的跨域請求是不會發送cookie等用戶認證憑據的,如果需要利用XMLHttpRequest來跨域請求,又要攜帶cookie到服務器,前端需要加上:withCredentials =
true
var xhr = new XMLHttpRequest(); xhr.open('GET', 'http://www.xxx.com/api'); xhr.withCredentials = true; xhr.onload = onLoadHandler; xhr.send();
withCredentials =
true , 必須在open后,send之前。
服務端的請求頭需要設置:
Access-Control-Allow-Credentials: true
如果服務端不設置該響應頭,瀏覽器會報錯,當然響應會被忽略不可用;
同時,服務端需指定一個域名(Access-Control-Allow-Origin:www.xxx.com),而不能使用泛型(Access-Control-Allow-Origin: *)不然即使設置了該頭部,cookie開始不能轉到服務器。
Cookie依然遵循同源政策,只有用服務器域名設置的Cookie才會上傳,其他域名的Cookie並不會上傳,且(跨源)原網頁代碼中的document.cookie也無法讀取服務器域名下的Cookie;
舉個粟子:
后端設置,Node.js
引入了中間件
1 const cookieParser=require("cookie-parser"); 2 app.use(cookieParser());
1 app.get("/getasync",(req,res)=>{ 2 setTimeout(function(){ 3 res.cookie("userid",'110',{maxAge:1000*60*60*24}) 4 res.writeHead(200, { 5 'Content-Type': 'text/html' 6 }); 7 res.write('返回') 8 res.end() 9 },1000) 10 })
客戶端:
1 ajax('http://127.0.0.1:8080/getasync','get',true,'null',function(res){ 2 console.log('我是異步2'+res) 3 })
瀏覽器:
cookie是在服務器設置的,通過請求頭傳給瀏覽器,瀏覽器再傳給服務器。
不了解瀏覽器那個圖?看看下面吧,瀏覽器Request Header和Response Header的內容
瀏覽器還可以通過setRequestHeader() 設置請求頭
語法: setRequestHeader(name, value)
name 頭部的名稱:這個參數不應該包括空白、冒號或換行
value 頭部的值:這個參數不應該包括換行
約束:此方法設置請求頭信息,必須在 調用 open( ) 之后 且 調用 send( ) 之前
xmlhttp.setRequestHeader("token","header-token-value"); // 可以定義請求頭帶給后端
1 function ajax(url,type,async,data,callback){ 2 var xhr = new XMLHttpRequest() 3 xhr.onreadystatechange = function(){ 4 if(xhr.readyState==4 && xhr.status == 200){ 5 callback(xhr.responseText) 6 } 7 } 8 var params = []; 9 for(var k in data){ 10 params.push(k+'='+data[k]) 11 } 12 var postData = params.join('&') 13 14 xhr.open(type,url,async) 15 xhr.withCredentials = true; 16 17 if(type === 'post'){ 18 xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded;charset=utf-8'); 19 xhr.send(postData); 20 }else{ 21 xhr.send(null) 22 } 23 }
另外,當瀏覽器獲取cookie后,通過JSONP請求的,也會攜帶cookie
1 function jsonp(url,data,callback){ 2 var cbName = 'callback_'+new Date().getTime() 3 var queryString = url.indexOf('?') == -1?'?':'&'; 4 for (var k in data) 5 { 6 queryString += k+'='+data[k]+'&'; 7 } 8 queryString += 'callback='+cbName; 9 var ele = document.createElement('script'); 10 ele.src = url + queryString; 11 document.body.appendChild(ele); 12 window[cbName] = function(data){ 13 callback(data); 14 document.body.removeChild(ele) 15 } 16 } 17 18 function send(){ 19 ajax('http://127.0.0.1:8080/getcookie','get',true,function(res){ 20 console.log('cookie') 21 }) 22 }
瀏覽器jsonp請求:
如果您在cookie中設置了HttpOnly屬性,那么通過js腳本將無法讀取到cookie信息,這樣能有效的防止XSS攻擊