js跨域总结

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引用另一个页面。

//获取页面中的iframe
var iframe = document.getElementById('myIFrame').contentWindow;
//注意:contentWindow
iframe.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,写法简单,前端和后台都无需过多代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值