对跨域的一些总结,方便日后查阅
跨域并非浏览器限制了发起跨站请求,而是跨站请求可以正常发起,但返回结果被浏览器拦截了,有些浏览器不允许从HTTPS协议的域 跨域访问 HTTP协议,比如Chrome和Firefox,这些浏览器在请求还未发出的时候就会拦截请求
同源策略
如果两个页面拥有相同的协议(protocol),端口,和域名,那么这两个页面就属于同一个源(origin),JavaScript 允许这种同源页面的数据互相通信。
一般web页面的端口号默认都是80例如:http://xxx.com/a.html 协议是http、端口:80、域名:xxx.com
若非同源,则以下行为会受到限制:
- Cookie、LocalStorage 和 IndexedDB 无法读取
- DOM 无法获得
- AJAX 请求不能发送
跨域方案
经典的JSONP
回调函数和数据(script标签可以加载并执行其他域JS文件)原理:站点A动态插入script标签,通过script标签引入一个js文件,这个js文件载入成功后会执行我们在url参数中指定的函数(站点B把要提供的数据作为参数传给一个站点A定义的全局函数),并且会把我们需要的json数据作为参数传入。
1
2
3
4
5
6<script src="http://xxx.com/data.php?callback=dosomething"></script>
<script type="text/javascript">
function dosomething(jsondata){
console.log(jsondata);
}
</script>js文件载入成功后,会执行我们在url参数中指定的函数(dosomething),并且会把我们需要的json数据(jsondata)作为参数传入。所以再次强调jsonp是需要服务器端的页面进行相应的配合的。
1
2
3
4
5
$callback = $_GET['callback'];
$data = {'name':'XXX',sex:'X',age:'X'};
echo $callback.'('.json_encode($data).')';缺点:1、 仅适应于HTTP的Get请求,不支持POST等其它类型的HTTP请求,不能提交大量数据;
2、 缺乏错误处理机制 3、 不能解决不同域的两个页面之间如何进行JavaScript调用的问题优点:1、 兼容性更好,在老版本的浏览器中可以运行
2、 请求完毕后可以通过调用callback的方式回传结果,方便调用子域名代理
在不同的子域 + iframe交互的时候,获取到另外一个 iframe 的 window对象是没有问题的,但是获取到的这个window的方法和属性大多数都是不能使用的解决方法:document.domain
例如:A页面:http://xxx.com/a.html,在这个页面里面有一个iframe,它的src是http://y.xxx.com/b.html
1
2
3
4
5
6
7
8//a.html
<iframe id = "iframe" src="http://y.xxx.com/b.html" onload = "test()"></iframe>
<script type="text/javascript">
document.domain = 'xxx.com';
function test(){
alert(document.getElementById('iframe').contentWindow);
}
</script>1
2
3
4//b.html
<script type="text/javascript">
document.domain = 'xxx.com';
</script>document.domain的设置是有限制的,我们只能把document.domain设置成自身或更高一级的父域,且主域必须相同。
CORS
跨域资源共享。定义了必须在访问跨域资源时,浏览器与服务器应该如何沟通.原理就是使用自定义的 HTTP 头部,让服务器能声明 哪些来源可以通过浏览器访问该服务器上的资源,从而决定请求或响应是应该成功还是失败,主要是通过设置响应头的 Access-Control-Allow-Origin 来达到目的的
more
- window.name
在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个window.name的,每个页面对window.name都有读写的权限,window.name是持久存在一个窗口载入过的所有页面中的。
- window.postMessage()
使用它来向其它的window对象发送消息,无论这个window对象是属于同源或不同源