同源策略如下:
- 同一域名下(http://www.a.com/a.js和 http://www.a.com/b.js)允许通信
- 同一域名不同文件夹下(http;//www.a.com/lab/a.js和http://www.a.com/script/b.js)允许通信
- 同一域名不同端口(http://www.a.com:8080/a.js和http://www.a.com/b.js)不允许通信
- 同一域名不同协议(http://www.a.com/b.js和https://www.a.com/a.js)不允许通信
- 域名和域名对应ip (http://ww.a.com/a.js和http://70.12.30.5/a.js)不允许通信
- 主域相同子域不同(http://www.a.com/a.js和http://www.script.a.com/b.js)不允许通信
- 不同域名不允许通信
特别注意两点:
第一:如果是协议和端口造成的跨域问题,前台是无能为力的
第二:在跨域问题上,域仅仅是通过“URL的首部”来识别而不会去尝试判断相同的ip地址对应着两个域或两个域是否在用一个ip上。
前端解决跨域问题
- 动态创建script(script标签不受同源策略的限制)
<script type="text/javascript">
function loadScript(url,func){
var head=document.head||document.getElementsByTagName('head')[0];
var script=document.createElement("script");
script.src=url;
script.onload=script.onreadystatechange=function(){
if(!this.readyState||this.readyState=='loaded'||this.reayState=="complete"){
script.onload=script.onreadystatechange=null;
}
};
head.insertBefore(script,head.firstChild);
}
window.baidu = {
sug: function(data){
console.log(data);
}
}
loadScript('http://suggestion.baidu.com/su?wd=w',function(){console.log('loaded')});
</script>
2 COR
CORS背后的思想是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是成功还是失败。
// IE中对CORS的实现是xdr
var xdr=new XDomainRequest();
xdr.onload=function(){
console.log(xdr.responseText);
}
xdr.open('get',"http://ww.baidu.com");
......
xdr.send(null);
//其他浏览器的实现就在xhr中
var xhr=new XMLHttpRequest();
xhr.onreadystatechange=function(){
if(xhr.readState==4){
if(xhr.status>=200&&xhr.status<304||xhr.status==304){
console.log(xhr.responseText);
}
}
}
xhr.open('get',"http://www.baidu.com");
......
xhr.send(null);
// 实现跨浏览器的CORS
function createCORS(method,url){
var xhr=new XMLHttpRequest();
if('withCredentials' in xhr){
xhr.open(method,url,true);
}else if(typeof XDomainRequest!='undefined'){
var xhr=new XDomainRequest();
xhr.open(method,url);
}else{
xhr=null;
}
return xhr;
}
var request=createCORS("get","http://www.baidu.com");
if(request){
request.onload=function(){
};
request.send();
}
3 JSONP
包含两部分:回调函数和数据。回调函数是当响应到来时要放在当前页面被调用的函数;数据就是传入回调函数的json数据,也就是回调函数的参数。
function handleResponse(response){
console.log('The response data:'+response.data);
}
var script=document.createElement("script");
script.src="http://www.baidu.com/json/?callback=handleResponse";
document.body.insertBefore(script,document.body.firstChild);
当我们通过script标签请求时,后台就会根据相应的参数来生成相应的json数据,最后这个返回的json数据就会被放在当前js文件中被执行,至此跨域通信完成。
但是JSONP存在安全问题并且确定JSONP请求失败不容易。