JavaScript跨域解决方案Word下载.docx
- 文档编号:8233666
- 上传时间:2023-05-10
- 格式:DOCX
- 页数:6
- 大小:23.15KB
JavaScript跨域解决方案Word下载.docx
《JavaScript跨域解决方案Word下载.docx》由会员分享,可在线阅读,更多相关《JavaScript跨域解决方案Word下载.docx(6页珍藏版)》请在冰点文库上搜索。
允许
同一域名下分歧文件夹
同一域名,分歧端口
不允许
同一域名,分歧协议
域名和域名对应ip
主域相同,子域分歧
同一域名,分歧二级域名(同上)
不允许(cookie这种情况下也不允许访问)
分歧域名
特别注意两点:
第一,如果是协议和端口造成的跨域问题“前台”是无能为力的,
第二:
在跨域问题上,域仅仅是通过“URL的首部”来识别而不会去检验考试判断相同的ip地址对应着两个域或两个域是否在同一个ip上.“URL的首部”指window.location.protocol+window.location.host,也可以理解为“Domains,protocolsandportsmustmatch”.
接下来简单地总结一下在“前台”一般处置跨域的法子,后台proxy这种方案牵涉到后台配置,这里就不管述了,有兴趣的可以看看yahoo的这篇文章:
《JavaScript:
UseaWebProxyforCross-DomainXMLHttpRequestCalls》
1、document.domain+iframe的设置
对主域相同而子域分歧的例子,可以通过设置document.domain的法子来解决.具体的做法是可以在=‘’;
然后通过a.html文件中创立一个iframe,去控制iframe的contentDocument,这样两个js文件之间就可以“交互”了.固然这种法子只能解决主域相同而二级域名分歧的情况,如果你异想天开的把的domian设为那显然是会报错地!
代码如下:
document.domain='
'
;
varifr=document.createElement('
iframe'
);
ifr.src='
='
none'
document.body.appendChild(ifr);
ifr.onload=function(){vardoc=ifr.contentDocument||ifr.contentWindow.document;
//在这里把持b.htmlalert(doc.getElementsByTagName("
h1"
)[0].childNodes[0].nodeValue);
};
这种方式适用于{,,,}中的任何页面相互通信.
备注:
某一页面的domain默认即是window.location.hostname.主域名是不带www的域名,例如,主域名前面带前缀的通常都为二级域名或多级域名,例如其实是二级域名.domain只能设置为主域名,不成以在中将domain设置为.
问题:
1、平安性,当一个站点()被攻击后,另一个站点()会引起平安漏洞.
2、如果一个页面中引入多个iframe,要想能够把持所有iframe,必需都得设置相同domain.
2、静态创立script
虽然浏览器默认禁止了跨域访问,但其实不由止在页面中引用其他域的JS文件,并可以自由执行引入的JS文件中的function(包括把持cookie、Dom等等).根据这一点,可以方便地通过创立script节点的方法来实现完全跨域的通信.具体的做法可以参考YUI的GetUtility
这里判断script节点加载完毕还是蛮有意思的:
ie只能通过script的readystatechange属性,其它浏览器是script的load事件.以下是部份判断script加载完毕的方法.
js.onload=js.onreadystatechange=function(){if(!
this.readyState||this.readyState==='
loaded'
||this.readyState==='
complete'
){//callback在此处执行js.onload=js.onreadystatechange=null;
}};
分歧的域之间,JavaScript只能做很有限的访问和把持,其实我们利用这些有限的访问权限就可以到达跨域通信的目的了.FIM(FragmentIdentitierMessaging)就是在这个年夜前提下被发明的.父窗口可以对iframe进行URL读写,iframe也可以读写父窗口的URL,URL有一部份被称为frag,就是#号及其后面的字符,它一般用于浏览器锚点定位,Server端其实不关心这部份,应该说HTTP请求过程中不会携带frag,所以这部份的修改不会发生HTTP请求,可是会发生浏览器历史记录.FIM的原理就是改变URL的frag部份来进行双向通信.每个window通过改变其他window的location来发送消息,并通过监听自己的URL的变动来接收消息.这个方式的通信会造成一些不需要的浏览器历史记录,而且有些浏览器不支持onhashchange事件,需要轮询来获知URL的改变,最后,URL在浏览器下有长度限制,这个制约了每次传送的数据量.
这个法子比力绕,可是可以解决完全跨域情况下的脚步置换问题.原理是利用location.hash来进行传值.在url:
#helloword中的‘#helloworld’就是location.hash,改变hash其实不会招致页面刷新,所以可以利用hash值来进行数据传递,固然数据容量是有限的.假设域名下的文件cs1.html要和域名下的cs2.html传递信息,cs1.html首先创立自动创立一个隐藏的iframe,iframe的src指向域名下的cs2.html页面,这时的hash值可以做参数传递用.cs2.html响应请求后再将通过修改cs1.html的hash值来传递数据(由于两个页面不在同一个域下IE、Chrome不允许修改parent.location.hash的值,所以要借助于域名下的一个代办署理iframe;
Firefox可以修改).同时在cs1.html上加一个按时器,隔一段时间来判断location.hash的值有没有变动,一点有变动则获取获取hash值.
先是下的文件cs1.html文件:
functionstartRequest(){varifr=document.createElement('
ifr.style.display='
ifr.src='
document.body.appendChild(ifr);
}functioncheckHash(){try{vardata=location.hash?
location.hash.substring
(1):
'
if(console.log){console.log('
Nowthedatais'
+data);
}}catch(e){};
}setInterval(checkHash,2000);
域名下的cs2.html:
//模拟一个简单的参数处置把持switch(location.hash){case'
#paramdo'
:
callBack();
break;
case'
#paramset'
//dosomething……break;
}functioncallBack(){try{parent.location.hash='
somedata'
}catch(e){//ie、chrome的平安机制无法修改parent.location.hash,//所以要利用一个中间的cnblogs域下的代办署理iframevarifrproxy=document.createElement('
ifrproxy.style.display='
ifrproxy.src='
//注意该文件在"
"
域下document.body.appendChild(ifrproxy);
}}
//因为parent.parent和自身属于同一个域,所以可以改变其location.hash的值parent.parent.location.hash=self.location.hash.substring
(1);
固然这样做也存在很多缺点,诸如数据直接流露在了url中,数据容量和类型都有限等……
AccessControl是比力超越的跨域方式,目前只在很少的浏览器中得以支持,这些浏览器可以发送一个跨域的HTTP请求(Firefox,谷歌Chrome等通过XMLHTTPRequest实现,IE8下通过XDomainRequest实现),请求的响应必需包括一个Access-Control-Allow-Origin的HTTP响应头,该响应头声明了请求域的可访问权限.例如对下的asset.php发送了一个跨域的HTTP请求,那么asset.php必需加入如下的响应头:
window对象的name属性是一个很特另外属性,当该window的location变动,然后重新加载,它的name属性可以依然坚持不变.那么我们可以在页面A中用iframe加载其他域的页面B,而页面B中用JavaScript把需要传递的数据赋值给window.name,iframe加载完成之后,页面A修改iframe的地址,将其酿成同域的一个地址,然后就可以读出window.name的值了.这个方式非常适合单向的数据请求,而且协议简单、平安.不会像JSONP那样不做限制地执行外部脚本.
文章较长列在此处方便于阅读,详细请看
.
5、使用HTML5postMessage
HTML5中最酷的新功能之一就是
跨文档消息传输CrossDocumentMessaging.下一代浏览器都将支持这个功能:
Chrome2.0+、InternetExplorer8.0+,Firefox3.0+,Opera9.6+,和Safari4.0+.Facebook已经使用了这个功能,用postMessage支持基于web的实时消息传递.
otherWindow.postMessage(message,targetOrigin);
otherWindow:
对接收信息页面的window的引用.可以是页面中iframe的contentWindow属性;
的返回值;
通过name或下标从取到的值.message:
所要发送的数据,string类型.targetOrigin:
用于限制otherWindow,“*”暗示不作限制
<
iframeid="
ifr"
src="
type="
text/javascript"
>
window.onload=function(){varifr=document.getElementById('
ifr'
vartargetOrigin='
//若写成'
就不会执行postMessage了ifr.contentWindow.postMessage('
Iwasthere!
targetOrigin);
/script>
scripttype="
window.addEventListener('
message'
function(event){//通过origin属性判断消息来源地址if(event.origin=='
){alert(event.data);
//弹出"
alert(event.source);
//对、index.html中window对象的引用//但由于同源战略,这里event.source不成以访问window对象}},false);
参考文章:
《精通HTML5编程》第五章——跨文档消息机制、
6、利用flash
flashURLLoader
flash有自己的一套平安战略,服务器可以通过crossdomain.xml文件来声明能被哪些域的SWF文件访问,SWF也可以通过API来确定自身能被哪些域的SWF加载.当跨域访问资源时,例如从域请求域上的数据,我们可以借助flash来发送HTTP请求.首先,修改域上的crossdomain.xml(一般寄存在根目录,如果没有需要手动创立),把加入到白名单.其次,通过FlashURLLoader发送HTTP请求,最后,通过FlashAPI把响应结果传递给JavaScript.FlashURLLoader是一种很普遍的跨域解决方案,不外需要支持iOS的话,这个方案就无能为力了.
FlashLocalConnection
页面上的双向通信也可以通过Flash来解决,FlashAPI中有LocalConnection这个类,该类允许两个SWF之间通过进程通信,这时SWF可以播放在自力的FlashPlayer或者AIR中,也可以嵌在HTML页面或者是PDF中.遵循这个通信原则,我们可以在分歧域的HTML页面各自嵌套一个SWF来到达相互传递数据的目的了.SWF通过LocalConnection交换数据是很快的,可是每次的数据量有40kb的年夜小限制.用这种方式来跨域通信过于复杂,而且需要了2个SWF文件,实用性不强.
7、JSONP
JSONP(JSONwithPadding)是一个简单高效的跨域方式,HTML中的script标签可以加载并执行其他域的javascript,于是我们可以通过script标识表记标帜来静态加载其他域的资源.例如我要从域A的页面pageA加载域B的数据,那么在域B的页面pageB中我以JavaScript的形式声明pageA需要的数据,然后在pageA中用script标签把pageB加载进来,那么pageB中的脚本就会得以执行.JSONP在此基础上加入了回调函数,pageB加载完之后会执行pageA中界说的函数,所需要的数据会以参数的形式传递给该函数.JSONP易于实现,可是也会存在一些平安隐患,如果第三方的脚本随意地执行,那么它就可以窜改页面内容,截获敏感数据.可是在受信任的双方传递数据,JSONP是非常合适的选择.
8、serverproxy
在数据提供方没有提供对JSONP协议或者window.name协议的支持,也没有对其它域开放访问权限时,我们可以通过serverproxy的方式来抓取数据.例如当域下的页面需要请求下的资源文件asset.txt时,直接发送一个指向/asset.txt的Ajax请求肯定是会被浏览器阻止.这时,我们在下配一个代办署理,然后把Ajax请求绑定到这个代办署理路径下,例如/proxy/,然后这个代办署理发送HTTP请求访问下的asset.txt,跨域的HTTP请求是在服务器端进行的,客户端并没有发生跨域的Ajax请求.这个跨域方式不需要和目标资源签订协议,带有侵略性,另外需要注意的是实践中应该对这个代办署理实施一定水平的呵护,比如限制他人使用或者使用频率.
9、CrossFrame
CrossFrame是FIM的一个变种,它借助了一个空白的iframe,不会发生过剩的浏览器历史记录,也不需要轮询URL的改变,在可用性和性能上都做了很年夜的改观.它的基来源根基理年夜致是这样的,假设在域上有页面A.html和一个空白代办署理页面proxyA.html,另一个域上有个页面B.html和一个空白代办署理页面proxyB.html,A.html需要向B.html中发送消息时,页面会创立一个隐藏的iframe,iframe的src指向proxyB.html并把message作为URLfrag,由于B.html和proxyB.html是同域,所以在iframe加载完成之后,B.html可以获得iframe的URL,然后解析出message,并移除该iframe.当B.html需要向A.html发送消息时,原理一样.CrossFrame是很好的双向通信方式,而且平安高效,可是它在Opera中无法使用,不外在Opera下面我们可以使用更简单的window.postMessage来取代.
总结
跨域的方法很多,分歧的应用场景我们都可以找到一个最合适的解决方案.比如单向的数据请求,我们应该优先选择JSONP或者window.name,双向通信我们采用CrossFrame,在未与数据提供方没有告竣通信协议的情况下我们也可以用serverproxy的方式来抓取数据.
罕见的分歧域间的页面制约dom元素包括:
window.location可以设置,但不能读取.其它的location属性和方法被禁止访问;
document.href可以设置,但不能读取.其它的document属性和方法被禁止访问;
iframe>
的src可以设置,但不能读取;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- JavaScript 解决方案