精华帖 (1) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (11)
|
|
---|---|
作者 | 正文 |
发表时间:2011-02-04
最后修改:2011-02-12
当然,“近乎完美”仅仅是个人观点,但如下所述,它确实简单而颇有效益!
一直在寻求一种自己满意的 JS 跨域方式(这里是指任意跨域),曾经了解过:
无意中看到一篇文章《使用 window.name 解决跨域问题》……豁然开朗! 俺的问题终于解决了。 对那个实现小改了一下,加了浏览器本地设置 Window.name 的功能,实现浏览器“本地”异域数据的传递(如从浏览器窗口A传递数据到窗口B,仅在本地进行,且两个域不同)——这会产生一个很蛙王的应用(下一篇文章《普通 http 网络下数据的安全传输》将详细说明,本文后有少量提及)。感谢网络! 也感谢愿意分享的技术达人! 下面贴出俺的代码,也分享一下,呵呵…… (注意:本地需要创建一个名为 proxy.html 的空文件) (function() { var _isIE = ( navigator.appName == "Microsoft Internet Explorer" ); var _removeNode = _isIE ? function() { var d; return function(n) { if(n && n.tagName != 'BODY') { d = d || document.createElement('div'); d.appendChild(n); d.innerHTML = ''; } } }() : function(n) { if(n && n.parentNode && n.tagName != 'BODY') { n.parentNode.removeChild(n); } }; /* [ Request by window.name ] * **************************************************************************** 借助 Window.name 实现 Js 的跨域访问。 1、 url 向外传值, callback 处理返回结果。 2、 返回页面中 JS 对 window.name 赋值。 返回页 <script language="JavaScript"> window.name = ... // 支持 JSON 字符串,可达~2MB </script> 若需同时进行多个请求,回调函数应是不同的函数实例。 iframe 的自由载入形成了异步机制。 */ wnRequest = { _doc: document, _proxyUrl: 'proxy.html' }; wnRequest.send = function( url, callback ) { if(! url || typeof url !== 'string') { return; } url += (url.indexOf('?') > 0 ? '&' : '?') + 'windowname=get'; var frame = this._doc.createElement('iframe'); frame._state = 0; this._doc.body.appendChild(frame); frame.style.display = 'none'; (function( el, type, fn ) { if (_isIE) { el.attachEvent('on' + type, fn); } else { el.addEventListener(type, fn, false); } })(frame, 'load', function() { if(frame._state == 1) { _getData(frame, callback); } else if(frame._state == 0) { frame._state = 1; //frame.contentWindow.location = wnRequest._proxyUrl; frame.contentWindow.location.replace(wnRequest._proxyUrl); } }); frame.src = url; }; // // 设置异域 Js 可访问的本地数据,客户端直接站间转递数据 // 注: // 即浏览器直接将数据转递给另一个域的窗口,数据不上网。 // 返回页代码: // <script type="text/javascript"> // if (window.name) { // //... 处理 name 值 // window.name = null; // } // // 升为顶级窗口,完成数据转递 // try { // top.location.hostname; // if (top.location.hostname != window.location.hostname) { // top.location.href =window.location.href; // } // } catch(e) { // top.location.href = window.location.href; // } // </script> // // wnRequest.setname = function( name, url ) { if(! url || typeof url !== 'string') { return; } url += (url.indexOf('?') > 0 ? '&' : '?') + 'windowname=loc'; var frame = this._doc.createElement('iframe'); frame._count = 0; this._doc.body.appendChild(frame); frame.style.display = 'none'; if (_isIE) { frame.name = name; } else { frame.contentWindow.name = name; } frame.src = url; }; // // 私用辅助 // var _clear = function(frame) { try { frame.contentWindow.document.write(''); frame.contentWindow.close(); _removeNode(frame); } catch(e) {} } var _getData = function(frame, callback) { try { var da = frame.contentWindow.name; } catch(e) {} _clear(frame); if(callback && typeof callback === 'function') { callback(da); } } })(); 使用: 如果需要同时访问多个异域文件,可以像下面这样写回调函数,浏览器异步载入 iframe 的机制形成了天生的 JS 跨域异步访问。 这是跨域请求的主页面 JS 调用: <script language="javascript"> var _str = '', _cnt = 0; function myfunc( id ) { return function( data ) { _str += id + ':' + data + '\n'; ++_cnt; if (_cnt >= 4) alert(_str); }; } var _links = [ { id: 4, url: 'http://www.aaa.com/test4.html' }, { id: 5, url: 'http://www.bbb.com/test5.html' }, { id: 6, url: 'http://www.ccc.com/test6.html' }, { id: 7, url: 'http://www.ddd.com/test7.html' } ]; function dosome() { for (var _i=0; _i<_links.length; ++_i) { wnRequest.send(_links[_i].url, myfunc(_links[_i].id)); } // 跨域本地数据转递 wnRequest.setname('这里可能是一串加密用的密钥哦,俺从 https 那边过来滴!', 'http://www.eee.com/test8.html'); } </script> http://www.aaa.com/test4.html 中的内容:(跨域网络数据传递) <script type="text/javascript"> window.name='返回的数据,可以是 JSON 格式'; </script> http://www.eee.com/test8.html 中的内容:(跨域本地数据转递应用。注意:这里是普通的 http 协议) <script type="text/javascript"> if (window.name) { alert(window.name); // 存储或处理 name 值 // 可存在 Cookie 中,如果不希望 Cookie 上传泄露出去,可设置其 secure 属性 window.name = null; } /* try { top.location.hostname; if (top.location.hostname != window.location.hostname) { top.location.href =window.location.href; } } catch(e) { top.location.href = window.location.href; } */ </script> 呵呵……是否期待下一篇文章《普通 http 网络下数据的安全传输》呢? 注: 附件包含本跨域实现和前几篇关于 JS 文字加密算法的实现代码。 =============================================================================== 修 订: frame.contentWindow.location = wnRequest._proxyUrl; 如此赋值在 firefox 中会导致历史记录的产生,可用 Location.replace() 代替,如下: frame.contentWindow.location.replace(wnRequest._proxyUrl); 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2011-02-05
这个方式,需要 A B域的东西都要在代码里做一点事情
还不如直接引用js |
|
返回顶楼 | |
发表时间:2011-02-05
zhangxingliang 写道 这个方式,需要 A B域的东西都要在代码里做一点事情
还不如直接引用js 愿闻其详 |
|
返回顶楼 | |
发表时间:2011-02-08
jsonp
|
|
返回顶楼 | |
发表时间:2011-02-09
听说过,今天才知道JSONP是这样啊,多谢LZ了,其实还是没明白为什么要跨域去传这些东西,还是用JS。。。
|
|
返回顶楼 | |
发表时间:2011-02-09
# for (var _i=0; _i<_links.length; ++_i) {
# wnRequest.send(_links[_i].url, myfunc(_links[_i].id)); # } # // 跨域本地数据转递 # wnRequest.setname('这里可能是一串加密用的密钥哦,俺从 https 那边过来滴!', 'http://www.eee.com 为什么setname()在send()的后面啊? 这样那些URL能得到传值吗? 不是很明白,,请指点啊 |
|
返回顶楼 | |
发表时间:2011-02-10
la_ka 写道 为什么setname()在send()的后面啊? 这样那些URL能得到传值吗? 不是很明白,,请指点啊
那只是个“用法”的示例,不是具体的应用 引用 for (var _i=0; _i<_links.length; ++_i) {
wnRequest.send(_links[_i].url, myfunc(_links[_i].id)); } 批量 send 的用法 引用 wnRequest.setname('这里可能是一串加密用的密钥哦,俺从 https 那边过来滴!', 'http://www.eee.com/test8.html');
本地不同域数据转递的用法 |
|
返回顶楼 | |
发表时间:2011-02-10
简单实用,很不错
|
|
返回顶楼 | |
发表时间:2011-02-10
可以跨浏览器吗,
|
|
返回顶楼 | |
发表时间:2011-02-10
个人觉得不如JSONP
|
|
返回顶楼 | |