js跨域总结

来源:互联网 发布:织梦cms百科 编辑:程序博客网 时间:2024/06/14 16:29

js跨域总结

什么是跨域

跨域,指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript施加的安全限制。所谓同源是指,域名,协议,端口均相同。任何一个不同在交流数据时就会产生跨域。

解决方法

1.document.domain + iframe

document.domain是当前网页的域名,如www.abc.com的document.domain=www.abc.com。这个变量可以被赋值,但是只能被赋值为当前域名或者基础域名。如www.abc.com和abc.com。其它赋值都会报错。
如果一个页面用iframe引入另外一个页面,只能看其内容,却不能操作其内容数据。但是如果两个网页的document.domain相同时,是可以互相操作页面内容的。
所以这种跨域的方法是将两个网页中document.domain设置为相同值,这也就决定了这个方法的使用情景,你能够设置两个页面的domian,同时这个设置要符合规定。

2.动态创建script标签

这个方法是利用script的src属性可跨域性质。
直接上例子(网上找的关于登陆判断的例子):

<script>  function request(id,url){       oScript = document.getElementById(id);       var head = document.getElementsByTagName("head").item(0);       if (oScript) {          head.removeChild(oScript);       }       oScript = document.createElement("script");       oScript.setAttribute("src", url);       oScript.setAttribute("id",id);       oScript.setAttribute("type","text/javascript");       oScript.setAttribute("language","javascript");       head.appendChild(oScript);       return oScript;  }  function userLogin(){      var username=document.getElementById('name').value;      var password=document.getElementById('password').value;       var url='http://127.0.0.1:8080/EasyCMS/login.jsp?name='+encodeURI(username)+'&password='+encodeURI(password)+'&s=' + (new Date()).getTime();      //alert("url="+url);      var login=request("loginScript",url);  }  function myloginState(state){        alert("ret:"+state);        if (state==0)        {          alert("登陆成功");        }        else        {             alert("登陆失败");        }  }  </script>  <body>  用户名:<input name="name" id="name" type="text" />  密码:<input name="password" id="password" type="password" />  <input name="" value="login" type="button" onclick="userLogin();" />  </body>

后台代码

String name=request.getParameter("name");  String password=request.getParameter("password");  if (name.equals("admin") && password.equals("admin"))  {      request.getSession().setAttribute("admin","admin");      %>      myloginState("0");       <%  }  else  {      %>          myloginState("1");       <%   }  %>  

解读:
前端页面中先定义好了动态创建script标签的方法和获取后台数据后的处理函数。这个动态创建标签的方法是动态创建script标签,同时将url设置为后台接口地址同时拼接页面中的数据,将数据发送至后台。
后台获取传过来的参数根据参数不同返回不同数据。这个数据必须跟前端商量,一般都是一个函数名加上后台获取的数据。因为src标签是代表的替换,所以前端这个标签最终会变成后台返回的语句,执行一个函数。而函数已经在页面中定义好,又获取从后台传过去的数据,从而实现跨域。
也可以将函数名也传至后台,这样后台写法更灵活一些。

3.jsonp

jsonp也是利用script标签的src属性跨域。
举例:

<script type="text/javascript">      function jsonpCallback(result) {          }      }  </script>  <script type="text/javascript" src="http://...?callback=jsonpCallback"></script>  

后端代码

$arr=array('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5);  $result=json_encode($arr);  //动态执行回调函数  $callback=$_GET['callback'];  echo $callback."($result)"; 

解读:
前端页面用script的src将函数名传至后台,后台获取函数名,返回一条包含函数名和参数的语句。前端得到返回值,获取参数,同时执行该函数,实现跨域。
该方法与动态创建script标签基本一样,只不过在需要发送一些页面中的参数时用动态创建script标签,jsonp方法无需传页面中参数,直接写标签即可,也可动态创建。

4.cors跨域

前端代码,在xhr的setRequestHeader方法中设置Origin属性,例:

xhr.setRequestHeader("Origin", "http://www.abc.com")

其中xhr是原生ajax的xhr对象,在jquery中的beforesend方法中可获取原生xhr对象

beforesend:function(xhr){    xhr.setRequestHeader("Origin", "http://www.abc.com")}

在后台中设置两个属性

Access-Control-Allow-Origin, "http://www.abc.com";"Access-Control-Allow-Methods, "GET, POST, PUT, DELETE";//当Access-Control-Allow-Origin设置为"*"时,前端无需设置请求头,可直接访问

5.postmessage

postmessage解决的是两个页面间的跨域通信,比如iframe嵌套页面等。
举例,一个页面通过iframe引用另一个页面。

//获取页面中的iframevar iframe = document.getElementById('myIFrame').contentWindow;//注意:contentWindowiframe.postMessage(message,uri)//message理论上可以是任何类型的数据,但是不同浏览器对其支持不同,尽量使用字符串,uri是目标uri。//在iframe中监听message事件window.addEventListener('message',function(event) {    if(event.origin !== 'http://davidwalsh.name') return;    console.log('message received:  ' + event.data,event);    event.source.postMessage('backmessage!',event.origin);},false);//event对象中包含很多属性,Origin是信息源域名,在接受信息处理前应判断源。data是接受的数据。sourse是信息源contentWindow的引用。

需要注意的是h5新增方法,注意兼容性。

其它方法

webcosket,window.name+iframe,服务器请求服务器是没有跨域限制的,而且上面集中方法已经涵盖常见的跨域情况,推荐cors,写法简单,前端和后台都无需过多代码。

原创粉丝点击