这是在面试迅雷的时候,迅雷面试官给我的一【访问 www.tangshuang.net 获取更多精彩内容】原创内容,盗版必究。个问题,我没有回答上来,回来之后,就对这著作权归作者所有,禁止商业用途转载。【版权所有】唐霜 www.tangshuang.net个问题进行了梳理,现在把它们总结一下。
【作者:唐霜】【版权所有】唐霜 www.tangshu【版权所有】唐霜 www.tangshuang.net【作者:唐霜】ang.net本文版权归作者所有,未经授权不得转载。1. 跨域的js文件
著作权归作者所有,禁止商业用途转载。【版权所有】唐霜 www.tangshu【版权所有】唐霜 www.tangshuang.net原创内容,盗版必究。ang.net这是js里面最基本的一种跨域形式,我们通【版权所有】唐霜 www.tangshuang.net【本文首发于唐霜的博客】过<script src>引本文作者:唐霜,转载请注明出处。本文版权归作者所有,未经授权不得转载。用非当前域名下的另外一个脚本文件。那么怎本文版权归作者所有,未经授权不得转载。【原创内容,转载请注明出处】么进行跨域数据的传递呢?其实很简单,当浏【版权所有】唐霜 www.tangshuang.net【转载请注明来源】览器在载入该js的时候,会阻塞整个页面的【版权所有,侵权必究】本文版权归作者所有,未经授权不得转载。执行,载入js文件完成之后,会立即执行文【访问 www.tangshuang.net 获取更多精彩内容】【原创内容,转载请注明出处】件内的程序,因此,我们可以这样去做:
【转载请注明来源】【本文受版权保护】【原创内容,转载请注明出处】<script>var data;</script>
<script src="http://anotherdomain.com/user_info.json?access_token=xxx" id="json"></script>
<script>
window.onload = function() {
if(typeof data == 'object') {
alert(data.name);
}
}
</script>
而我们在上面的#json的src文件正好著作权归作者所有,禁止商业用途转载。【未经授权禁止转载】给data赋值,在另外一个域名下,根据我本文作者:唐霜,转载请注明出处。未经授权,禁止复制转载。们传入的一些值,返回不同的结果:
【本文首发于唐霜的博客】【访问 www.tangshuang.n转载请注明出处:www.tangshuang.net【本文受版权保护】et 获取更多精彩内容】【未经授权禁止转载】原创内容,盗版必究。data = {name: 'kiddy',age: 18};
这样,相当于通过引入一个js给data进本文版权归作者所有,未经授权不得转载。本文版权归作者所有,未经授权不得转载。行赋值。而每次希望改变data的值的时候转载请注明出处:www.tangshuang.net【本文受版权保护】,通过脚本动态加载一个新的脚本就可以了:
本文版权归作者所有,未经授权不得转载。【原创内容,转载请注明出处】【原创内容,转载请注明出处】var script = document.getElementById('script');
script.src = 'xxxxxx.json?acess_token=xxxx';
但是这种形式有一个缺点,就是在服务端文件【作者:唐霜】【原创内容,转载请注明出处】内,会多出data = 这一段对于的信息【原创不易,请尊重版权】【未经授权禁止转载】,和我们平时直接输出的json数据不同,【关注微信公众号:wwwtangshuangnet】【本文首发于唐霜的博客】视觉感会差很多。有没有一种方法可以实现输【原创不易,请尊重版权】【访问 www.tangshuang.net 获取更多精彩内容】出json,同时有完成相同的操作呢?
【本文首发于唐霜的博客】著作权归作者所有,禁止商业用途转载。【访问 www.tangshuang.n本文版权归作者所有,未经授权不得转载。原创内容,盗版必究。et 获取更多精彩内容】【本文受版权保护】2. jsonp
【版权所有】唐霜 www.tangshu【转载请注明来源】【访问 www.tangshuang.net 获取更多精彩内容】ang.net本文版权归作者所有,未经授权不得转载。著作权归作者所有,禁止商业用途转载。相信很多人都听过这个大名鼎鼎的技术,JS原创内容,盗版必究。著作权归作者所有,禁止商业用途转载。ONP实际上已经成为一种协议,主要用于X【版权所有,侵权必究】转载请注明出处:www.tangshuang.netmlHttpRequest跨域请求。实际【转载请注明来源】转载请注明出处:www.tangshuang.net上,我们用jsonp以解决上面的那个问题转载请注明出处:www.tangshuang.net【本文首发于唐霜的博客】。首先,我们来看下跨域js文件的另一种操【本文受版权保护】【作者:唐霜】作形式:
本文作者:唐霜,转载请注明出处。著作权归作者所有,禁止商业用途转载。本文作者:唐霜,转载请注明出处。<script>
function alertName(data) {
alert(data.name);
}
</script>
<script src="http://anotherdomain.com/xxx.josnp?callback=alertName"></script>
这是我们在原本文件中写到的,而我们在远方原创内容,盗版必究。【本文受版权保护】的josnp目标页面这样输出:
【版权所有,侵权必究】【原创内容,转载请注明出处】alertName({name: "Kafi", age: 15});
也就是说在当前页面定义了一个函数,然后在著作权归作者所有,禁止商业用途转载。未经授权,禁止复制转载。远端的js文件中执行这个函数,而函数本身【转载请注明来源】本文版权归作者所有,未经授权不得转载。是有一个data参数的,在远端就直接通过【作者:唐霜】【转载请注明来源】后台程序,把要传递的数据作为参数传递给要本文作者:唐霜,转载请注明出处。【未经授权禁止转载】执行的函数。这就是jsonp的原型。但是本文作者:唐霜,转载请注明出处。【转载请注明来源】,这样还是很麻烦,比起之前输出data 本文版权归作者所有,未经授权不得转载。原创内容,盗版必究。= {}的形式反而更复杂了,而且还必须通未经授权,禁止复制转载。转载请注明出处:www.tangshuang.net过一个 callback来让远端接收指定原创内容,盗版必究。未经授权,禁止复制转载。的函数名。所以,这中形式不是我们最终的j【版权所有,侵权必究】【作者:唐霜】sonp,而jsonp的合理操作是:
著作权归作者所有,禁止商业用途转载。【访问 www.tangshuang.n【关注微信公众号:wwwtangshuangnet】原创内容,盗版必究。et 获取更多精彩内容】【访问 www.tangshuang.n【原创不易,请尊重版权】未经授权,禁止复制转载。et 获取更多精彩内容】jsonp(url,function(data) {
// 利用data进行数据处理
});
其中,url就是远端返回数据的地址,它可【原创内容,转载请注明出处】【原创内容,转载请注明出处】以完全按照我们的想法,返回一个纯json【关注微信公众号:wwwtangshuangnet】【本文受版权保护】数据,而这个数据,将被作为参数传递给js【版权所有,侵权必究】【本文受版权保护】onp的第二个参数函数,也就是data。原创内容,盗版必究。【原创内容,转载请注明出处】当然,这是一种模型,我们并没有实现它,但本文版权归作者所有,未经授权不得转载。本文作者:唐霜,转载请注明出处。它的原理,就是我们上面所述的,通过回调函本文版权归作者所有,未经授权不得转载。本文作者:唐霜,转载请注明出处。数执行已经输出的数据。
【作者:唐霜】未经授权,禁止复制转载。转载请注明出处:www.tangshua本文版权归作者所有,未经授权不得转载。【版权所有】唐霜 www.tangshuang.netng.net【关注微信公众号:wwwtangshua本文作者:唐霜,转载请注明出处。【访问 www.tangshuang.net 获取更多精彩内容】ngnet】不过需要注意的是,由于跨域操作,一般js【原创不易,请尊重版权】未经授权,禁止复制转载。onp都是异步执行的,也就是说, 上面f【原创不易,请尊重版权】【版权所有】唐霜 www.tangshuang.netunction函数体的程序,肯定要等到u著作权归作者所有,禁止商业用途转载。本文作者:唐霜,转载请注明出处。rl返回数据之后才会执行,这就会导致在j【未经授权禁止转载】转载请注明出处:www.tangshuang.netsonp后面的javascript程序会【本文首发于唐霜的博客】著作权归作者所有,禁止商业用途转载。先于这个function执行。
【版权所有】唐霜 www.tangshu转载请注明出处:www.tangshuang.net原创内容,盗版必究。ang.net原创内容,盗版必究。3. HTML5的window.post转载请注明出处:www.tangshuang.net【转载请注明来源】Message
【原创内容,转载请注明出处】原创内容,盗版必究。在javascript的跨域中,除了上面【作者:唐霜】【未经授权禁止转载】两种数据请求的情况,还有一种就是页面之间【访问 www.tangshuang.net 获取更多精彩内容】本文作者:唐霜,转载请注明出处。的通信问题。“请求”和“通信”是两种不同【版权所有】唐霜 www.tangshuang.net【未经授权禁止转载】的行为,请求是当前页面主动去请求另外一个本文版权归作者所有,未经授权不得转载。【本文受版权保护】页面的数据,而通信往往是指当前页面和其他【原创内容,转载请注明出处】【版权所有】唐霜 www.tangshuang.net页面可以实现数据同步,也就是当自己的数据未经授权,禁止复制转载。本文作者:唐霜,转载请注明出处。变化时,别的页面可以感知到,或者别的页面【本文受版权保护】【本文受版权保护】数据变化时,自己可以做出相应的动作。
【版权所有,侵权必究】【本文受版权保护】HTML5的window.postMes【访问 www.tangshuang.net 获取更多精彩内容】【版权所有】唐霜 www.tangshuang.netsage就是一种通信手段,它可以实现不同【原创不易,请尊重版权】未经授权,禁止复制转载。页面之间的信息通知,甚至是跨域的,比如我著作权归作者所有,禁止商业用途转载。【作者:唐霜】们看下面的代码:
未经授权,禁止复制转载。【关注微信公众号:wwwtangshua原创内容,盗版必究。【本文首发于唐霜的博客】ngnet】本文版权归作者所有,未经授权不得转载。【转载请注明来源】window.onmessage = function(e) {
e = e || event;
var data = e.data;
var origin = e.origin;
var source = e.source;
data = JSON.parse(data);
alert(data.name);
}
这是我们希望当前页面在接收到postMe著作权归作者所有,禁止商业用途转载。【转载请注明来源】ssage通知的时候,所做出的响应。那么【原创不易,请尊重版权】【版权所有】唐霜 www.tangshuang.net另外一个页面如何进行通知呢?
未经授权,禁止复制转载。【本文受版权保护】著作权归作者所有,禁止商业用途转载。【本文首发于唐霜的博客】otherWindow.postMessage(message, targetOrigin);
这个otherWindow是一个比较麻烦【本文受版权保护】本文作者:唐霜,转载请注明出处。的事情,我们下面再讲。先看postMes未经授权,禁止复制转载。【作者:唐霜】sage方法的两个参数,第一个就是消息体著作权归作者所有,禁止商业用途转载。著作权归作者所有,禁止商业用途转载。,是字符串,第二个是允许哪些域名下的wi原创内容,盗版必究。【版权所有】唐霜 www.tangshuang.netndow对象接收postMessage的【原创内容,转载请注明出处】原创内容,盗版必究。内容,它包含协议和域名,也就是说你想让那【未经授权禁止转载】未经授权,禁止复制转载。个页面接收消息,就要在这里填写这个页面所原创内容,盗版必究。【原创内容,转载请注明出处】在的域名,例如“http://127.0本文版权归作者所有,未经授权不得转载。【原创内容,转载请注明出处】.0.1”或者“https://www.【访问 www.tangshuang.net 获取更多精彩内容】未经授权,禁止复制转载。yourdomain.com”,如果不限【版权所有】唐霜 www.tangshuang.net本文作者:唐霜,转载请注明出处。制域名,就直接用*代替,比如:
【版权所有】唐霜 www.tangshu原创内容,盗版必究。转载请注明出处:www.tangshuang.netang.net【访问 www.tangshuang.n【转载请注明来源】原创内容,盗版必究。et 获取更多精彩内容】原创内容,盗版必究。otherWindow.postMessage('{name: "kiidy", age: 10}','*');
接下来我们讲otherWindow,它其转载请注明出处:www.tangshuang.net未经授权,禁止复制转载。实是指代某一个窗口。我们上面讲targe【关注微信公众号:wwwtangshuangnet】【未经授权禁止转载】tOrigin用*代替的话,就不限制域名【访问 www.tangshuang.net 获取更多精彩内容】【原创不易,请尊重版权】,但是实际上,只有otherWindow【原创内容,转载请注明出处】【未经授权禁止转载】可以接收到这个消息通知。也就是说,如果你未经授权,禁止复制转载。【转载请注明来源】的targetOrigin进行了限制,那未经授权,禁止复制转载。本文作者:唐霜,转载请注明出处。么otherWindow必须在该域名下面【未经授权禁止转载】【转载请注明来源】,如果不在,那就接收不到消息,而如果使用原创内容,盗版必究。未经授权,禁止复制转载。*的话,无论otherWindow在哪个【原创不易,请尊重版权】【版权所有,侵权必究】域名下,都可以接收消息。可是这里有一个B【版权所有,侵权必究】【版权所有,侵权必究】UG不知道你有没有发现,就是otherWindow的存在是一切的前提,如果没有找到otherWindow,一转载请注明出处:www.tangshuang.net未经授权,禁止复制转载。切都是百搭。所以,我们一般即使用*,也只【未经授权禁止转载】【本文首发于唐霜的博客】能在所有浏览器打开的窗口中,找到一个ot【本文首发于唐霜的博客】【本文首发于唐霜的博客】herWindow,不可能找到第二个同名本文版权归作者所有,未经授权不得转载。【访问 www.tangshuang.net 获取更多精彩内容】的窗口。
【转载请注明来源】【转载请注明来源】【版权所有】唐霜 www.tangshu【转载请注明来源】【版权所有,侵权必究】ang.net浏览器一个标签就是一个窗口,这个窗口大部原创内容,盗版必究。转载请注明出处:www.tangshuang.net分情况下是匿名的,但是也有一些情况下不匿【未经授权禁止转载】【未经授权禁止转载】名,比如使用window.open打开的【本文受版权保护】【本文首发于唐霜的博客】窗口window.open(pageURL,name,parameters),其中name就是这个窗口的名称,可以作著作权归作者所有,禁止商业用途转载。著作权归作者所有,禁止商业用途转载。为我们这里的otherWindow,还有【关注微信公众号:wwwtangshuangnet】【原创内容,转载请注明出处】一种情况就是iframe窗口对象,虽然它【关注微信公众号:wwwtangshuangnet】【关注微信公众号:wwwtangshuangnet】也是匿名的,但是我们却可以确定ifram本文作者:唐霜,转载请注明出处。【关注微信公众号:wwwtangshuangnet】e从而确定该匿名窗口的所属,使用 doc著作权归作者所有,禁止商业用途转载。原创内容,盗版必究。ument.getElementById【版权所有】唐霜 www.tangshuang.net【本文受版权保护】(‘iframe_id转载请注明出处:www.tangshuang.net转载请注明出处:www.tangshuang.net217;).contentWindow来未经授权,禁止复制转载。【未经授权禁止转载】作为otherWindow。我们看下面这【作者:唐霜】【作者:唐霜】个例子:
// 当前页面http://127.0.0.1/a.html
<iframe id="f" src="http://localhost/b.html"></iframe>
<script>
var f=document.getElementById("f");
f.onload=function() {
f.contentWindow.postMessage("SB","http://localhost");
}
</script>
上面这段代码通过一个iframe确定了o【关注微信公众号:wwwtangshuangnet】【本文首发于唐霜的博客】therWindow,所以只要这个ifr【原创内容,转载请注明出处】【版权所有,侵权必究】ame没有被销毁,它加载完的时候,【关注微信公众号:wwwtangshuangnet】【原创不易,请尊重版权】221;SB”这个字符串就会未经授权,禁止复制转载。原创内容,盗版必究。被推送到iframe里面的窗口去。而在i【版权所有,侵权必究】本文作者:唐霜,转载请注明出处。frame里面的窗口,我们使用下面的js原创内容,盗版必究。【版权所有,侵权必究】来接收:
本文版权归作者所有,未经授权不得转载。未经授权,禁止复制转载。【原创内容,转载请注明出处】<script>
onmessage = function(e) {
e=e||event;
document.write("我是",e.data);
};
</script>
这样,iframe里面的内容就会发生变化【本文受版权保护】著作权归作者所有,禁止商业用途转载。。
本文作者:唐霜,转载请注明出处。著作权归作者所有,禁止商业用途转载。但是这种方法和我们前面介绍的方法,存在这著作权归作者所有,禁止商业用途转载。【未经授权禁止转载】么几个不足之处:
本文作者:唐霜,转载请注明出处。未经授权,禁止复制转载。【原创不易,请尊重版权】- 必须是不同的浏览器窗口之间通信,换一个浏本文版权归作者所有,未经授权不得转载。未经授权,禁止复制转载。览器,换一个设备,就没任何作用了 【本文首发于唐霜的博客】【原创不易,请尊重版权】
- otherWindow难以灵活运用,无法【转载请注明来源】著作权归作者所有,禁止商业用途转载。实现不同的浏览器标签之间进行通信(这需要本文作者:唐霜,转载请注明出处。【未经授权禁止转载】我们使用更高级的websocket技术) 【作者:唐霜】【本文受版权保护】著作权归作者所有,禁止商业用途转载。
所以,一般这种方法的时候,会用在一些比较原创内容,盗版必究。【未经授权禁止转载】高阶的场景,也就是和浏览器的worker【访问 www.tangshuang.net 获取更多精彩内容】本文作者:唐霜,转载请注明出处。搭配起来处理,其技术难度也相对高很多。
原创内容,盗版必究。【作者:唐霜】【原创内容,转载请注明出处】4. window.name
【原创内容,转载请注明出处】原创内容,盗版必究。window.name是window对象【版权所有,侵权必究】【本文受版权保护】的一个特殊方法,它可以实现在不同的窗口之著作权归作者所有,禁止商业用途转载。【版权所有】唐霜 www.tangshuang.net间变化的时候,仍然保持同一个值,即使不同原创内容,盗版必究。转载请注明出处:www.tangshuang.net域名下的页面,仍然有效。
【本文受版权保护】【访问 www.tangshuang.n【版权所有,侵权必究】【关注微信公众号:wwwtangshuangnet】et 获取更多精彩内容】本文版权归作者所有,未经授权不得转载。【未经授权禁止转载】比如我们在a.html中写入:
【原创内容,转载请注明出处】转载请注明出处:www.tangshua转载请注明出处:www.tangshuang.net转载请注明出处:www.tangshuang.netng.net【原创不易,请尊重版权】【版权所有】唐霜 www.tangshu【未经授权禁止转载】【作者:唐霜】ang.netwindow.name = '{name: "dotiy"}';
当页面跳转到b.html中我们可以使用下【访问 www.tangshuang.net 获取更多精彩内容】【原创内容,转载请注明出处】面的方法来获取:
原创内容,盗版必究。著作权归作者所有,禁止商业用途转载。【版权所有,侵权必究】var name = window.name;
这是很有意思的一种数据传输方式,但是wi【转载请注明来源】本文版权归作者所有,未经授权不得转载。ndow.name的值可以随时被改,该了【未经授权禁止转载】原创内容,盗版必究。之后在下一个新打开的页面中就会使用新的值未经授权,禁止复制转载。【访问 www.tangshuang.net 获取更多精彩内容】。
本文版权归作者所有,未经授权不得转载。【原创不易,请尊重版权】著作权归作者所有,禁止商业用途转载。另外,它也可以在iframe的窗口对象中【关注微信公众号:wwwtangshuangnet】原创内容,盗版必究。生效,但是仅针对该窗口,即iframe.本文版权归作者所有,未经授权不得转载。【关注微信公众号:wwwtangshuangnet】contentWindow.name,如【原创内容,转载请注明出处】【关注微信公众号:wwwtangshuangnet】果是这样,就可以让iframe内的页面和未经授权,禁止复制转载。【关注微信公众号:wwwtangshuangnet】宿主页面通信,在宿主页面使用:
【关注微信公众号:wwwtangshua【关注微信公众号:wwwtangshuangnet】原创内容,盗版必究。ngnet】【本文首发于唐霜的博客】【本文受版权保护】转载请注明出处:www.tangshua著作权归作者所有,禁止商业用途转载。【未经授权禁止转载】ng.netvar name = document.getElementById('iframe_id').contentWindow.name;
这样就取到了iframe中这个页面设置的【本文首发于唐霜的博客】【版权所有】唐霜 www.tangshuang.netwindow.name值,从而实现了跨域本文作者:唐霜,转载请注明出处。【本文受版权保护】数据传输。
【版权所有】唐霜 www.tangshu【版权所有,侵权必究】著作权归作者所有,禁止商业用途转载。ang.net【原创内容,转载请注明出处】5. document.domain
【关注微信公众号:wwwtangshua本文作者:唐霜,转载请注明出处。【原创不易,请尊重版权】ngnet】未经授权,禁止复制转载。转载请注明出处:www.tangshua【版权所有,侵权必究】【原创不易,请尊重版权】ng.net原创内容,盗版必究。其实这不算一种方法,而是javascri原创内容,盗版必究。著作权归作者所有,禁止商业用途转载。pt本身的一种机制。简单的说就是通过修改原创内容,盗版必究。【版权所有】唐霜 www.tangshuang.netdocument.domain来使子域名【转载请注明来源】【访问 www.tangshuang.net 获取更多精彩内容】下的页面,可以和父域名下的页面通信。注意【转载请注明来源】【版权所有】唐霜 www.tangshuang.net,这里用的是“通信”,也就是说不可以通过ajax的方法,从父域名的地址中【转载请注明来源】【转载请注明来源】得到数据。一般这种跨域用在iframe中【转载请注明来源】原创内容,盗版必究。:
转载请注明出处:www.tangshua著作权归作者所有,禁止商业用途转载。未经授权,禁止复制转载。ng.net原创内容,盗版必究。本文作者:唐霜,转载请注明出处。著作权归作者所有,禁止商业用途转载。document.domain = 'rootdomain.com';
这种方法的限制太多,主要包括:
【关注微信公众号:wwwtangshua未经授权,禁止复制转载。本文版权归作者所有,未经授权不得转载。ngnet】【原创不易,请尊重版权】【版权所有】唐霜 www.tangshu【原创内容,转载请注明出处】本文版权归作者所有,未经授权不得转载。ang.net- 这一句代码必须在两个页面中都加以举出,即著作权归作者所有,禁止商业用途转载。【转载请注明来源】使该页面是在根域名下面。 【作者:唐霜】未经授权,禁止复制转载。
- 只能由子域名向父域名扩展,而不能在父域名本文版权归作者所有,未经授权不得转载。本文作者:唐霜,转载请注明出处。的页面中要求document.domai本文作者:唐霜,转载请注明出处。【关注微信公众号:wwwtangshuangnet】n为子域名 【本文首发于唐霜的博客】【本文受版权保护】著作权归作者所有,禁止商业用途转载。
- 只能解决iframe这类弱处理,而不能真【转载请注明来源】【转载请注明来源】正实现跨域的数据请求 【关注微信公众号:wwwtangshua转载请注明出处:www.tangshuang.net【转载请注明来源】ngnet】【本文受版权保护】
最后,在我们使用ajax进行跨域请求的时本文作者:唐霜,转载请注明出处。原创内容,盗版必究。候,还可以通过在服务端进行一些配置,可以本文版权归作者所有,未经授权不得转载。【关注微信公众号:wwwtangshuangnet】让ajax在请求对应域名时,可以被正常接【本文受版权保护】著作权归作者所有,禁止商业用途转载。受。请看《服务端php解决jquery ajax跨【未经授权禁止转载】【关注微信公众号:wwwtangshuangnet】域请求restful api问题及实践》《jquery ajax 请求中多出现一次转载请注明出处:www.tangshuang.net【版权所有】唐霜 www.tangshuang.netOPTIONS请求及其解决办法》这两篇文章,可以帮你解决服务端是php【转载请注明来源】【作者:唐霜】的应用程序的配置方法。
【访问 www.tangshuang.n【访问 www.tangshuang.net 获取更多精彩内容】【访问 www.tangshuang.net 获取更多精彩内容】et 获取更多精彩内容】【作者:唐霜】未经授权,禁止复制转载。【关注微信公众号:wwwtangshua【原创不易,请尊重版权】【作者:唐霜】ngnet】2016-04-22 8903 ajax


