跨域請求下cookie的理解


傳統的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攻擊

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM