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,写法简单,前端和后台都无需过多代码。
- js 跨域总结
- js跨域总结
- js跨域方式总结
- js跨域总结及解决办法
- js作用域总结
- js变量作用域总结
- ajax跨域和js跨域解决方案总结
- js跨域总结(jsonp,postMessage,CORS)
- JS总结
- js总结
- JS总结
- js总结
- js总结
- JS总结
- js总结
- js总结
- JS总结
- js总结
- 2017.7.14. 最长公共子序列
- 数据库连接池
- MAC上安装LLVM
- 关于mybaits的缓存
- Django编写RESTful API(三):基于类的视图
- js跨域总结
- 各协议的协议号和端口号
- Java 中的成员内部类
- spark-streaming-kafka-0-8版本 的java连接ZK例子
- c++相关学习书籍
- MIT eecs 6.00 problemset3
- 01链表-单向静态链表
- java Spring 4.0基础学习(一)
- 第三课 Tensorflow实现人工神经网络