跨域问题常常会遇到。做了一下整理。
仅用于主域相同,子域不同的跨域(iframe+设置document.domain)
这种情况需要主域相同,即使用同一协议同一端口,且主域相同(例如aa.cnblogs.com和bb.cnblogs.com).这时可以使用iframe实现跨域,需要将document.domain设置成相同的,就可以访问数据了。
页面1:
<html> <head> <script> document.domain = "cnblogs.com"; </script> </head> <body> <iframe src="http://localhost:8080/test/2.html" id="subFrame"> </iframe> <script> document.getElementById('subFrame').onload = function(){ var d = document.getElementById('i').contentWindow; d.a(); }; </script> </body> </html>
页面2:
<html> <head> <script> document.domain = "cnblogs.com"; function a(){ alert("hi"); } </script> </head> <body> </body> </html>
这样1页面就可以访问到2页面中的a方法了。
动态创建script标签
script标签不受同源策略的限制,可以利用动态创建的script来加载其他域的js文件。并可以执行引入的JS文件中的function(包括操作cookie、Dom等等)。根据这一点,可以方便地通过创建script节点的方法来实现完全跨域的通信。具体的做法可以参考YUI的Get Utility.但是安全问题必须考虑。
var script = document.createElement('script');
script.src = "http://crossdomain.com/js/*.js";
document.body.appendChild(script);
然后还可以监听是否加载完毕,添加callback:
js.onload = js.onreadystatechange = function() { if (!this.readyState || this.readyState === 'loaded' || this.readyState === 'complete') { // callback js.onload = js.onreadystatechange = null; } };
使用JSONP
JSON with Padding是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问。
使用JSONP的理由:由于 JSON 只是一种含有简单括号结构的纯文本,因此许多通道都可以交换 JSON 消息。因为同源策略的限制,我们不能在与外部服务器进行通信的时候使用 XMLHttpRequest。而JSONP是一种可以绕过同源策略的方法,即通过使用 JSON 与 <script> 标记相结合的方法,从服务端直接返回可执行的JavaScript函数调用或者JavaScript对象。
<script type="text/javascript"> function jsonpCallback(result) { alert(result.msg); } </script> <script type="text/javascript" src="http://crossdomain.com/jsonServerResponse?jsonp=jsonpCallback"></script>
其中 jsonCallback 是客户端注册的,获取跨域服务器上的json数据后,回调的函数。
http://crossdomain.com/jsonServerResponse?jsonp=jsonpCallback
这个 url 是跨域服务器取 json 数据的接口,参数为回调函数的名字,返回的格式为:
jsonpCallback({ msg:'this is json data'})
原理:首先在客户端注册一个callback, 然后把callback的名字传给服务器。此时,服务器先生成 json 数据。然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的参数 jsonp.最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。客户端浏览器,解析script标签,并执行返回的javascript文档,此时数据作为参数,传入到了客户端预先定义好的 callback 函数里.(动态执行回调函数) .其实说白了,就是客户端定义一个函数(如a),请求地址后服务器端返回的结果是调用a函数,需要的数据都放在了a函数的参数里面。
这个过程是需要服务器配合完成的。
例子:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Demo</title> </head> <body> <script type="text/javascript"> function say(words) { alert(words); } </script> <script type="text/javascript" src="demo.js"></script> </body> </html>
其中demo.js:
say("Hello, everyone!");
还有其他的比较常用的方法,比如后台代理的方式。后台代理文档和js都可以跨域访问。