除了jsonp这个主流的解决方案外,还有其他四个常用的跨域请求方案适用于不同的场景。
# 图片ping
图片可以从任何URL中加载,故将img的src设置成其他域的URL,即可实现跨域。还有一个注意的地方是图片的加载是异步的,所以把图片的渲染必须放到回掉函数onload中,具体看以下示例代码:
<!DOCTYPE html>
<html>
<head>
<title>images ping</title>
<script type="text/javascript">
var img = new Image();
img.src = 'http://wozien.com/asset/images/html5.jpg'; // 异步加载图片
img.onload = function(){
console.log('sucessful');
document.body.appendChild(img); //渲染dom必须放在回掉函数里面,不然会报错
}
img.error = function(){
console.log('error');
}
</script>
</head>
<body>
<!-- <img src="'http://wozien.com/asset/images/html5.jpg'"> -->
</body>
</html>
#CORS(跨资源共享)
iE实例化了XDR对象(XDomainRequest),该对象只能访问到responseText,用onerror()检测异常,用onload检测请求出成功,其他和xhr对象方法几乎没区别。其他主流浏览器像ff,chrome实例化了XHR对象(XMLHttpRequest),和ajax一样,但是url要使用绝对地址。其中的限制:
- 不能发送和接受cookie
- 不能设置http头部信息和获取头部信息
#document.domain(解决不同域框架见的通信问题)
1.父框架只能获取子框架中的window对象(但该对象毫无用处,既不能用该对象对获取子框架中的其他属性),如下代码会报错:
<!DOCTYPE html>
<html>
<head>
<title>window.domain</title>
<script type="text/javascript">
function onLoad(){
var win = document.getElementById('iframe').contentWindow;
// var doc = win.document; //获取不到document
}
</script>
</head>
<body>
<iframe id="iframe" src="http://wozien.com/test/b.html" οnlοad="onLoad()"></iframe>
</body>
</html>
2.在父框架和子框架的js代码中设置document.domain为两个框架中页面所在的主域,前提两个页面的主域必须相同,不然该方法无效的。
#window.name
1.原理:在同一窗口的生命周期内加载的所有页面共用window.name属性,同时拥有读写权限。
比如在本地index.html设置name的值,在2秒后加载服务器b.html页面,b.html可以获取之前index.html设置的值。
index.html:
<!DOCTYPE html>
<html>
<head>
<title>window.name</title>
<script type="text/javascript">
window.name = 'this is from client message';
window.setTimeout(function(){
window.location = 'http://wozien.com/test/b.html';
},2000);
</script>
</head>
<body>
</body>
</html>
b.html:
<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript">
alert(window.name);
</script>
</head>
<body>
</body>
</html>
结果:
2.以上就是利用window.name进行跨域的原形,那么如何做到不刷新url的前提下获取跨域页面的window.name的值?
--在本地的index页面中加入一个隐藏的框架iframe,src先设置为我们要加载的远程服务器的页面url,并且在远程页面中把要传输信息封装成字符串设置为window.name的值,在iframe加载完远程页面后设置为本地随便的一个页面,这样最外层框架top才能获取自框架的window.name的值,不然会造成跨域限制。
index.html
<!DOCTYPE html>
<html>
<head>
<title>window.name</title>
<script type="text/javascript">
function getDate(){
var iframe = document.getElementById('proxy');
iframe.onload = function(){
alert(iframe.contentWindow.name);
}
iframe.src = 'index1.html';
}
</script>
</head>
<body>
<iframe id="proxy" src="http://wozien.com/test/b.html" style="display: none" οnlοad="getDate()"></iframe>
</body>
</html>
服务器页面代码b.html:
<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript">
window.name = 'remote origin set window property'
</script>
</head>
<body>
</body>
</html>
这样就完成了利用window.name进行跨域信息交换。以上就是现在常用的集中跨域解决方案,另外html5也有相应的API,回去再撸!