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