http://www.ibm.com/developerworks/cn/web/wa-aj-jsonp1/
同源策略阻止从一个域上加载的脚本获取或操作另一个域上的文档属性。也就是说,受到请求的 URL 的域必须与当前 Web 页面的域相同。这意味着浏览器隔离来自不同源的内容,以防止它们之间的操作。这个浏览器策略很旧,从 Netscape Navigator 2.0 版本开始就存在。
克服该限制的一个相对简单的方法是让 Web 页面向它源自的 Web 服务器请求数据,并且让 Web 服务器像代理一样将请求转发给真正的第三方服务器。尽管该技术获得了普遍使用,但它是不可伸缩的。另一种方式是使用框架要素在当前 Web 页面中创建新区域,并且使用 GET 请求获取任何第三方资源。不过,获取资源后,框架中的内容会受到同源策略的限制。
克服该限制更理想方法是在 Web 页面中插入动态脚本元素,该页面源指向其他域中的服务 URL 并且在自身脚本中获取数据。脚本加载时它开始执行。该方法是可行的,因为同源策略不阻止动态脚本插入,并且将脚本看作是从提供 Web 页面的域上加载的。但如果该脚本尝试从另一个域上加载文档,就不会成功。幸运的是,通过添加 JavaScript Object Notation (JSON) 可以改进该技术。
首先设置 hosts 文件为(下同):
127.0.0.1 www.c.com 127.0.0.1 www.d.com
http://www.d.com/cd/demo.html :
<script type="text/javascript"> $(document).ready(function(){ // use jquery $("#jsonp").click(function(){ $.getJSON("http://www.c.com/cd/data-jsonp.php?callback=?", function(response){ if(response){ alert('output: a: ' + response.a + ', b: ' + response.b); } else { alert('error'); } }); }); // dynamic create script $("#jsonp-append").click(function(){ appendScript('http://www.c.com/cd/data-jsonp.php?callback=callbackFunc'); }); }); // jsonp callback function function callbackFunc(response) { if(response){ alert('output: a: ' + response.a + ', b: ' + response.b); } else { alert('error'); } } // dynamic create script function appendScript(src) { //creat script var head = document.getElementsByTagName("head")[0]; var script = document.createElement("script"); script.setAttribute("src", src); script.setAttribute("type", "text/javascript"); script.charset = "utf-8"; // after script loaded, we remove the script script.onload = script.onreadystatechange = function(){ if (!this.readyState || this.readyState == "loaded" || this.readyState == "complete") { setTimeout(function(){ head.removeChild(script); }, 50); } }; // insert script head.appendChild(script); } </script> <a href="#" id="jsonp">获取数据(jquery)</a> <a href="#" id="jsonp-append">获取数据</a>
http://www.c.com/cd/data-jsonp.php :
$callback = isset($_GET['callback']) ? $_GET['callback'] : ''; echo "{$callback}(" . json_encode(array('a' => 1, 'b' => 2)) . ")";
http://blog.monstuff.com/archives/000280.html
http://www.d.com/cd/demo.html :
<script type="text/javascript" src="FlashHelper.js"></script> <script type="text/javascript"> $(document).ready(function(){ // flash & crossdomain.xml crossdomain $("#flash").click(function(){ flashCall(); }); }); // flash & crossdomain.xml crossdomain function flashCallback() { var response = FlashHelper.getFlash().GetVariable("retText"); // convert to json object response = eval("("+response+")"); alert('output: a: ' + response.a + ', b: ' + response.b); } function flashCall() { var url = 'http://www.c.com/cd/data.php'; var method = 'get'; var body = ''; var contentType = 'application/x-www-form-urlencoded'; var fs = FlashHelper.getFlash(); fs.XmlHttp(url, "flashCallback", method, body, contentType); } </script> <a href="#" id="flash">获取数据</a> <script type="text/javascript"> // flash & crossdomain.xml crossdomain FlashHelper.writeFlash(); </script>
http://www.c.com/cd/data.php :
echo json_encode(array('a' => 1, 'b' => 2));
http://www.c.com/crossdomain.xml :
<?xml version="1.0"?> <!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd"> <cross-domain-policy> <allow-access-from domain="*.c.com"/> <allow-access-from domain="*.d.com"/> </cross-domain-policy>
http://www.d.com/cd/demo.html :
<script type="text/javascript"> $(document).ready(function(){ // iframe cross domain by location.hash $("#clientform").submit(function(){ $("#serverframe").attr('src', 'http://www.c.com/cd/iframe-a.html?' + Math.floor(Math.random() * 10000) + '#' + $("#bgcolor").val()); return false; }); }); </script> <form id="clientform"> 设置 iframe 的背景色: <br /> <select id="bgcolor"> <option value="" selected>选择颜色</option> <option value="white">白色</option> <option value="black">黑色</option> <option value="red">红色</option> <option value="green">绿色</option> <option value="blue">蓝色</option> </select> <button type="submit" id="changecolor">Go!</button> </form> <iframe id="serverframe" width="210" height="150" frameborder="1" src="http://www.c.com/cd/iframe-a.html#white"></iframe>
http://www.c.com/cd/iframe-a.html :
<form id="serverform"> 设置父页面的背景色: <br /> <select id="pbgcolor"> <option value="" selected>选择颜色</option> <option value="white">白色</option> <option value="black">黑色</option> <option value="red">红色</option> <option value="green">绿色</option> <option value="blue">蓝色</option> </select> <button type="submit" id="pchangecolor">Go!</button> </form> <iframe id="iframe-agent" height="0" width="0" src="http://www.d.com/cd/iframe-agent.html" style="display:none"></iframe> <script type="text/javascript"> var hashVal = window.location.hash.substr(1); document.body.style.backgroundColor = hashVal; // iframe cross domain by location.hash $("#serverform").submit(function(){ var iframeagent = document.getElementById("iframe-agent"); iframeagent.src = iframeagent.src.split('#')[0] + "?" + Math.floor(Math.random() * 10000) +"#" + $("#pbgcolor").val(); return false; }); </script>
http://www.d.com/cd/iframe-agent.html :
<script type="text/javascript"> var hash_color = window.location.hash.substr(1); //var parentw = window.parent.parent.document.getElementById("cd-iframe"); //parentw.style.backgroundColor = hash_color; window.parent.parent.document.body.style.backgroundColor = hash_color; </script>
http://blog.csdn.net/lenel/archive/2007/10/24/1841483.aspx
如 bbs.xxx.com 的页面用 iframe 嵌入到 www.xxx.com 中, 一级域名都是 xxx.com
在父窗口和iframe内部分别加上: document.domain="xxx.com";
之后2个页面就等于在同一域名下,通过window.parent oIframe.contentDocument就可以相互访问,进行无障碍的JS通信
http://hi.baidu.com/thinkinginlamp/blog/item/5e2a02084f1dafd163d9865f.html
http://www.d.com/cd/setcookie.php :
echo '<script src="http://www.c.com/cd/data-cookie.php?id=www.d.com"></script>';
http://www.c.com/cd/data-cookie.php :
header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"'); $cookie = !empty($_GET['id']) ? $_GET['id'] : 'none'; setcookie("cd-p3p", $cookie, time() + 3600, "/", ".c.com");
访问 http://www.d.com/cd/setcookie.php , 这时候可以看到 www.c.com 的cookie 已经设置成功