跨域的理解
跨域的理解
什么是跨域?
JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象。但在安全限制的同时也给注入iframe或是ajax应用上带来了不少麻烦。这里把涉及到跨域的一些问题简单地整理一下。
首先什么是跨域,简单地理解就是因为JavaScript同源策略的限制,a.com 域名下的js无法操作b.com或是c.a.com域名下的对象。更详细的说明可以看下表:
1 | http://www.a.com/a.js http://www.a.com/b.js |
同一域名下 | 允许 |
2 | http://www.a.com/lab/a.js http://www.a.com/script/b.js |
同一域名下不同文件夹 | 允许 |
3 | http://www.a.com:8000/a.js http://www.a.com/b.js |
同一域名,不同端口 | 不允许 |
4 | http://www.a.com/a.js https://www.a.com/b.js |
同一域名,不同协议 | 不允许 |
5 | http://www.a.com/a.js http://70.32.92.74/b.js |
域名和域名对应ip | 不允许 |
6 | http://www.a.com/a.js http://script.a.com/b.js |
主域相同,子域不同 | 不允许 |
7 | http://www.a.com/a.js http://a.com/b.js |
同一域名,不同二级域名(同上) | 不允许(cookie这种情况下也不允许访问) |
8 | http://www.cnblogs.com/a.js http://www.a.com/b.js |
不同域名 | 不允许 |
注意两点:
第一:如果是协议和端口造成的跨域问题“前台”是无能为力的;
第二:在跨域问题上,域仅仅是通过“URL的首部”来识别而不会去尝试判断相同的ip地址对应着两个域或两个域是否在同一个ip上。 “URL的首部”指window.location.protocol +window.location.host,也可以理解为“Domains, protocols and ports must match”。
动态创建script(JSONP)
虽然浏览器默认禁止了跨域访问,但并不禁止在页面中引用其他域的JS文件,并可以自由执行引入的JS文件中的function(包括操作cookie、Dom等等)。根据这一点,可以方便地通过创建script节点的方法来实现完全跨域的通信。具体的做法可以参考YUI的Get Utility
这里判断script节点加载完毕还是蛮有意思的:ie只能通过script的readystatechange属性,其它浏览器是script的load事件。以下是部分判断script加载完毕的方法。
封装后的jsonp
1 document.onclick = function(){
2 var url = "http://localhost/jsonp/data/jsonp3.php";
3 jsonp(url,function(res){
4 alert(res)
5 },{
6 user:"admin",
7 pass:123,
8 // 根据后台指定的字段名,传入回调函数名,传给后台
9 zxc:"ewqrwer213213213",
10 // 用来保存后台接收的 回调函数名所在的字段名,传给自己的函数
11 columnName:"zxc"
12 })
13 }
14
15 function jsonp(url,callback,data){
16 // 解析要发送的数据
17 data = data || {};
18 var str = "";
19 for(var i in data){
20 str += `${i}=${data[i]}&`;
21 }
22 // 将数据拼接到url
23 url = url + "?" + str.slice(0,str.length-1);
24
25 // jsonp的功能:1.创建script
26 var script = document.createElement("script");
27 script.src = url;
28 document.body.appendChild(script);
29
30 // jsonp的功能:2.创建准备被资源执行的全局函数
31 window[data[data.columnName]] = function(res){
32 callback(res);
33 }
34 }