JavaScript跨域方法学习总结

来源:互联网 发布:速卖通seo 编辑:程序博客网 时间:2024/05/18 03:44

JavaScript跨域:

URL

说明

是否允许通信

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:8000/a.js 
http://www.a.com/b.js

同一域名,不同端口

不允许

http://www.a.com/a.js 
https://www.a.com/b.js

同一域名,不同协议

不允许

http://www.a.com/a.js 
http://70.32.92.74/b.js

域名和域名对应ip

不允许

http://www.a.com/a.js 
http://script.a.com/b.js

主域相同,子域不同

不允许

http://www.a.com/a.js 
http://a.com/b.js

同一域名,不同二级域名(同上)

不允许(cookie这种情况下也不允许访问)

http://www.cnblogs.com/a.js 
http://www.a.com/b.js

不同域名

不允许

 

JavaScript请求了不属于自己所在域的资源,违背同源策略,产生跨域。

(1)协议不同,比如http和https。

(2)域名或ip不同。

(3)端口不同。

 

跨域解决方案:

1、script标签跨域方案。

Script标签并无同域策略限制,是可以跨域获取脚本文件的。

客户端代码:

<!DOCTYPEhtml PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><htmlxmlns="http://www.w3.org/1999/xhtml"><head>    <title></title>    <scripttype="text/javascript">         var result = null;        window.onload = function () {            var script =document.createElement("script");            script.type ="text/javascript";            script.src ="http://192.168.0.101/ExampleBusinessApplication.Web/web2.aspx";             var head =document.getElementsByTagName("head")[0];            head.insertBefore(script,head.firstChild);         };         function callback(data) {            result = data;        }         function b_click() {            alert(result.name);        }    </script></head><body>    <input type="button"value="click me!" onclick="b_click();" /></body></html>


服务端代码:

protectedvoid Page_Load(object sender, EventArgs e)        {            string result ="callback({\"name\":\"zhangsan\",\"date\":\"2012-12-03\"})";             Response.Clear();            Response.Write(result);            Response.End();        }


2、jsonp跨域方案。

Jsonp的实现原理即是script标签跨域方式。

Jsonp跨域的服务端和script标签跨域是一样的,都要用callback(+data+)格式返回数据;

服务端代码:

protectedvoid Page_Load(object sender, EventArgs e)        {            string callback =Request.QueryString["jsoncallback"];//从请求头中获取callback方法名            string result = callback +"({\"name\":\"zhangsan\",\"date\":\"2012-12-03\"})";             Response.Clear();            Response.Write(result);            Response.End();        }


客户端代码:

$.ajax({                async: false,                url:"http://192.168.0.5/Web/web1.aspx",                type: "GET",                dataType: 'jsonp',                //jsonp的值自定义,如果使用jsoncallback,那么服务器端,要返回一个jsoncallback的值对应的对象.                jsonp: 'jsoncallback',                //要传递的参数,没有传参时,也一定要写上                  data: null,                timeout: 5000,                //返回Json类型                  contentType: "application/json;utf-8",                //服务器段返回的对象包含name,data属性.                success: function (result) {                    alert(result.date);                },                error: function (jqXHR,textStatus, errorThrown) {                    alert(textStatus);                }            });


3、document.domain跨子域方案。

所谓跨子域,就是通过设置document.domain将两个不同域的资源放在同一个父域下面,然后两者就可以正常交互了。

A页面代码(http://www.example.com/a.html):

<html><head>  <script>   document.domain = "example.com";    function aa(){      alert("p");   }  </script></head><body>   <iframe src="http://example.com/b.html"id=”i”>     </iframe>   <script>  document.getElementById('i').onload =function(){          var d =document.getElementById('i').contentWindow;          d.a();           };   </script> </body></html>


B页面代码(http://example.com/b.html):

<html> <head>  <script>    document.domain = " example.com";    function a(){    alert("c");     }  </script> </head> <body> </body></html>


注意:document.domain的设置是有限制的,我们只能把document.domain设置成自身或更高一级的父域,且主域必须相同。例如:www.org.example.com 中某个文档的document.domain 可以设成www.org.example.com、org.example.com 、example.com中的任意一个,但是不可以设成 ftp.www.org.example.com,因为这是当前域的子域,也不可以设成baidu.com,因为主域已经不相同了。

注意:document.domain的跨域必须是依托于一个html通过iframe的代理链接到另一个html,如果是ajax直接访问,这是行不通的。

主页面代码:

<!DOCTYPEhtml PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><htmlxmlns="http://www.w3.org/1999/xhtml" ><head>    <title>跨域获取数据</title>    <scripttype="text/javascript">    function domainData(url, fn)    {        var isFirst = true;        var iframe =document.createElement('iframe');        iframe.style.display = 'none';        var loadfn = function(){            if(isFirst){                iframe.contentWindow.location ='http://a.com/null.html';//动态生成iframe载入a页面。                isFirst = false;            } else {                fn(iframe.contentWindow.name);               iframe.contentWindow.document.write('');                iframe.contentWindow.close();               document.body.removeChild(iframe);                iframe.src = '';                iframe = null;            }        };        iframe.src = url;        if(iframe.attachEvent){            iframe.attachEvent('onload',loadfn);        } else {            iframe.onload = loadfn;        }                document.body.appendChild(iframe);    }    </script></head><body> </body>    <scripttype="text/javascript">    domainData('http://b.com/data.html',function(data){        alert(data);    });</script></html>


B页面代码:

<script>  window.name = '需要跨域传递的数据';</script>


 

4、window.name跨域方案。

Window的name属性存在于一个窗口的生命周期内,即使用window.location载入的界面都会共享这个name属性,且不会重置。

因此,可以我们可以通过这个name属性传递想要的数据。

主页面代码:

<!DOCTYPEhtml PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><htmlxmlns="http://www.w3.org/1999/xhtml" ><head>    <title>跨域获取数据</title>    <script type="text/javascript">    function domainData(url, fn)    {        var isFirst = true;        var iframe =document.createElement('iframe');        iframe.style.display = 'none';        var loadfn = function(){            if(isFirst){                iframe.contentWindow.location ='http://a.com/null.html';//动态生成iframe载入a页面。                isFirst = false;            } else {                fn(iframe.contentWindow.name);               iframe.contentWindow.document.write('');                iframe.contentWindow.close();               document.body.removeChild(iframe);                iframe.src = '';                iframe = null;            }        };        iframe.src = url;        if(iframe.attachEvent){//判断是否为IE浏览器,因为IE支持attachEvent            iframe.attachEvent('onload',loadfn);        } else {            iframe.onload = loadfn;        }                document.body.appendChild(iframe);    }    </script></head><body> </body>    <scripttype="text/javascript">    domainData('http://b.com/data.html',function(data){        alert(data);    });</script></html>


B页面代码:

<script>  window.name = '需要跨域传递的数据';</script>


5、HTML5的window.postMessage跨域方案。

A页面代码:

<script>functiononLoad(){variframe=document.getElementById(‘iframe’);varwin=iframe.contentWindow;win.postMessage(“你好”,*);//第一个参数为需要传递的消息,第二个为接收消息的域,可以为通配符。}</script>


B页面代码:

<script>Window.onmessage=function(e){//注册事件接收消息;e=e||event;//获取时间对象alert(e.data);}</script>


6、cors跨域方案。

在服务器为response响应头添加跨域许可,可以使用通配符“*”。

(跨域请求可以是post方式或者get方式请求。)

服务端:

header("Access-Control-Allow-Origin:http://www.a.com");


客户端代码:

$.ajax("www.cros.com/api/data",{   type: "GET",   xhrFields: {     withCredentials: true  },   crossDomain: true,   success: function(data, status, xhr) {   } }); 

本篇以摘抄、收集为主。 

参考文档:

http://www.cnblogs.com/oneword/archive/2012/12/03/2799443.html

http://www.cnblogs.com/zjfree/archive/2011/02/24/1963591.html

http://narutolby.iteye.com/blog/1464436

http://www.cnblogs.com/2050/p/3191744.html


0 0
原创粉丝点击