什么是跨域?
js同源策略的限制,a.com 域名下的js无法操作b.com 和c.a.com 域名下的对象。
当协议、子域名、主域名、端口号中任意一个不相同时,都算作不同域。 不同域之间互相请求资源,就算作“跨域”。
例如:http://www.abc.com/index.html 请求 http://www.efg.com/service.php。
有一点必须要注意: 跨域并不是请求发不出去,请求能发出去,服务端能收到请求饼正常返回结果,只是结果被浏览器拦截了。
跨域方法:
汇总:
1. jsonp 跨域, 原理: script标签可以跨域,只支持get请求。 安全问题会受到威胁。
2. cors 跨域,通过后端服务器实现,Access-Control-Allow-Origin。
3. postMessage window的一个属性方法
4. webscoket
5. nginx 方向代理
6. iframe跨域
1. 具有src属性的html标签
原理: 所有具有src属性的HTML标签都是可以跨域的
在浏览器中,<script>、<img>、<link>、<iframe> 这几个标签是可以加载跨域资源的,并且加载的方式相当于一次普通的get请求。
2. jsonp跨域
原理:sript标签是可以跨域的,而且跨域脚本中以直接回调当前脚本的函数
script标签是可以加载异域的js并执行的,通过预先设定好的callback函数来实现和母页面的交互,即JSONP跨域,原理,有个callback函数,对它的使用有一个典型的方式,JSONP只支持get请求。
前端代码:
<script type="text/javascript"> function dosometing(jsondata) { // 处理获得的json数据 } </script> <script src="http://haorooms.com/data.php?callback=dosometing"></script>
后端代码:
<?php $callback = $_GET[‘callback‘]; // 得到回调函数名 $data = array(‘a‘,‘b‘,‘c‘); // 要返回的数据 echo $callback.‘(‘.json_encode($data).‘)‘
3. 跨域资源共享 (CORS)
原理:服务器设置Access-Control-Allow-Origin HTTP 响应头后,浏览器将允许跨域请求
CORS 是HTML5标准提出的跨域资源共享,支持GET、POST等所有HTTP请求。CORS需要服务器端设置Access-Control-Allow-Origin头,否则浏览器会因为安全策略拦截返回的信息。
配置文件:
Access-Control-Allow-Origin: * # 允许所有域名访问 Access-Control-Allow-Origin: http://a.com # 只允许所有域名访问
4. document.domain
原理: 相同主域名不同子域名下的页面,可以设置document.domain 让它们同域
我们只需要在跨域的两个页面中设置document.domain 就可以了。 修改document.domain 的方法只适用于不同子域的框架间的交互,要载入iframe页面
例如:
1. 在页面:
http://a.example.com/a.html
设置document.domain
代码:
<iframe id = "iframe" src="http://b.example.com/b.html" onload="test()"> </iframe> <script type="text/javascript"> document.domain= "example.com"; // 设置成主域 function test() { alert(document.getElementById(‘iframe‘).contentWindow); // contentWindow 可获得子窗口的window对象 } </script>
2. 在页面
http://b.example.com/b.html
中设置document.domain
代码:
<script> document.domain = "example.com"; // 在iframe载入这个页面也设置document.domain, 使之与主页面的document.domain 相同 </script>
5. window.name
原理: window 对象有个name属性,该属性有个特征: 即在一个窗口(window) 的生命周期内,窗口载入的所有页面都是共享一个window.name的,每个页面对window.name 都有读写的权限, window.name 是持久存在一个窗口载入过的所有页面中。
6. window.postMessage
原理:h5 新增的psotMessage方法,通过postMessage来传递信息,对方可以通过监听message事件来监听信息。可跨主域名及双向跨域。
这里有两个页面
1. agent.com/index.html
2. server.com/remote.html
本地代码index.html
<body> <iframe id="proxy" src="http://server.com/remote.html" onload="postaMsg()" style="display: none"> </iframe> <script type="text/javascript"> var obj = { msg: ‘hello world‘ } function postMsg() { var iframe = document.getElementById(‘proxy‘); var win = iframe.contentWindow; win.postMessage(obj,‘http://server.com‘); } </script> </body>
postMessage 的使用方法:
otherWindow.postMessage(message, targetOrigin);
· otherWindow: 只目标窗口, 也就是给哪个window发消息,是window.frames 属性的成员或者由window.open 方法创建的窗口
· message: 要发送的消息,类型为String、Object
· targetOrigin: 是限定消息接收范围,不限制使用 *
server.com 上remote.html ,监听message 事件,并检查来源是否是要通信的域。
<head> <script> window.onmessage = function(e) { if (e.origin !== "http://localhost:8088") return; alert(e.data.msg + "from" + e.origin) } </script> </head>