跨域请求下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攻击

 

posted @ 2019-01-15 17:37  soso辉  阅读(2659)  评论(0编辑  收藏  举报