1.跨域的由来
浏览器为了保证网站安全,如限制a网站的cookie不被b网站读取,故浏览器禁止非同源情况下进行ajax请求,cookie访问,dom操作。非同源是指URL中协议,域名和端口有一项以上不同。然而,在某些特殊的业务场景下,我们需要获取非同源的数据,故诞生了跨域。
2.CORS(Cross-Origin Resource Sharing,跨域资源共享)
CORS是W3C规定的标准跨域方式,其基本思想是使用自定义的http头部让浏览器与服务器进行沟通,从而决定请求或响应是否成功。
与xhr的区别:
1>.cookie不会随请求发送,也不会随响应返回
2>.只能设置http请求头里面的content-type
3>.不能访问响应头信息
浏览器的兼容:
IE8-IE10是xdr(XDomainRequest),其它使用XMLHttpRequest
兼容写法:
function createCorsRequest(method,url){
var xhr = new XMLHttpRequest();
if(“withCredentials” in xhr){
xhr.open(method,url,true);
}else if(typeof XDomainRequest != “undefined”){
xhr= new XDomainRequest();
xhr.open(method,url);
}else{
xhr = null;
}
return xhr;
}
整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。
因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。
3.其它跨域
1.jsonp
JSONP是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,老式浏览器全部支持,服务器改造非常小。
它的基本思想是,网页通过添加一个<script>元素,向服务器请求JSON数据,这种做法不受同源政策限制;服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。
注意,该请求的查询字符串有一个callback参数,用来指定回调函数的名字,这对于JSONP是必需的,即后台服务器返回的函数名要与URL中参数一致。
写法:
var script = document.createElement(“script”);
script.type = “text/javascript”;
script.src = “http://xx/json/?callback=handlefn”;
document.body.insertBefore(script, document.body.firstChild);
function handlefn(data){console.log(data)}
2.图片ping
一种利用img进行跨域的技术,和jsonp利用<script>元素一样,因为网页可以加载任何网页中的图片。
主要的作用是用于在线广告跟踪浏览量,用户查看页面次数等
用法:
var img = new Image();
img.src = “http://xx.com/img/xx.png”;
img.onload = img.onerror = function(){n=n+1;}
3.Comet
sse和Web Sockets
sse支持长轮训,短轮训和HTTP流
长轮询是跟服务器发起一个http请求后,服务器不是立马返回数据,而是等数据有更新后在返回,返回后客户端在发请求,以此类推。
短轮训则是定时的向服务器发起请求,服务器不管数据有无更新都返回结果,由前端去判断数据是否已经更新。
HTTP流则是在页面整个生命周期内只使用一个http连接。由服务器主动周期性的向客户端推送数据。
web sockets是在一个单独的持久的连接上提供双全工,双向通信,使用的是一种新的通信协议。
总结:
处理ajax的跨域可以选择JSONP、CORS,服务端设置代理、WebSocket。如果主域相同,处理多级子域之间的通信可以选择document.domain,处理不同域之间的iframe,子窗口可以选择window.name、window.postMessage、location.hash来解决。