同源策略有两个限制:(1)不能经过ajax去请求不一样源中的数据(2)浏览器中不一样域的框架之间不能进行js交互php
这些限制必定程度上保证了web通讯的安全性,但也带来了诸多不便,因此有时候咱们须要使用一些跨域方法来获取其余域中的数据。css
首先有必要知道什么状况下须要跨域,域名、端口和协议三者只要有一个不相同时,就须要跨域,其中域名包括主域和子域。
我总结了如下8种跨域的方法,前五种是只能单向通讯,后三种能够实现双向通讯。html
这个是W3C出的一个标准,它容许浏览器向跨域服务器发送XMLHttpRequest请求,可是否成功取决于服务器。大部分浏览器都已经支持CORS了。前端
使用CORS来跨域和普通的AJAX对前端来讲没什么区别,不须要作什么额外的事,只是请求和响应头部会有一些关于跨域的信息。html5
2.jsonpweb
json+paddingajax
原理:浏览器请求script资源时不受同源策略的限制,而且请求到后是当即执行的。json
作法:声明一个全局函数,而后动态建立一个script标签,src属性是请求资源地址+获取函数的字段名+函数名,服务器收到后,返回一段js代码,给上面那个函数传入参数,并执行,一般参数就是请求的数据。
优势:不受浏览器兼容性的限制。
缺点:只能发送GET请求。须要服务器端和客户端提早规定好。跨域
3.CSST,利用css跨域传输文本浏览器
优势:比JSONP更安全,不须要执行跨站脚本
缺点:只有支持CSS的浏览器才能执行
原理:跟JSONP有些相似,利用css没有同源限制,请求css,设置其content属性为请求内容便可。
4.图像Ping
原理和jsonP,CSST相似,利用图像没有同源限制,请求图像,图像Ping多用于跟踪用户点击页面或动态广告曝光次数。
5.经过window.name跨域
window对象有个name属性,该属性有个特征:即在一个窗口(window)的生命周期内,窗口载入的全部的页面都是共享一个window.name的,每一个页面对window.name都有读写的权限,为了安全起见它是以字符串的格式传递信息的,容量高达2M,他的使用方法是这样: 首先将要传送的信息复制给window.name属性,而后再这个窗口下打开另外一个页面,最后在第二个页面中读取window.name的值,获得第一个页面发送的信息。
6.设置document.domain
页面框架之间,也就是frame和iframe之间是能够获取彼此的window对象的,可是不能够获取window的属性和方法,只有一个html5新引入的方法例外,这个稍后再说
可是若是二者的document.domain同样的话,就能够获取别的页面的属性和文件了,但domian的设置也是有限制的,因此这个方法也有必定限制性
7.window.postMessage方法
也是用于不一样frame间的通讯,一个frame调用postMessage方法,传入两个参数,第一个是要发送的消息,第二个是接受消息的window所在的域。接受消息的窗口监听message事件便可
8.websocket
websocket能够在一个单独的持久连接上提供全双工的双向通讯,它没有同源限制,因此在须要双向通讯时websocket是一个比较不错的跨域选择。
var ws = new WebSocket("http://aa.com/server.php"); ws.onmessage = function(event){ var data = event.data; //处理 }; var message = { time: 10, content: "我是Claiyre" }; //发送JSON格式的数据 ws.send(JSON.stringify(message)); ws.onclose = function(event){ event.wasClean //布尔值,表示连接是否已经明确地关闭 event.code //状态码 event.reason //缘由短语 } ws.close(); //调用后ws.readyState的值变为2(正在关闭)