历史版本2 :跨域调用 JS 返回文档
编辑时间:
内容长度:图片数:目录数:
修改原因:
1. 问题描述编辑
用户想要实现在自己的OA系统里点击按钮,就能触发我们的报表的提交事件。但是如果报表和他们的OA不在一个应用中,会存在js跨域调用的权限问题,这个问题该如何解决呢?
2. 实现思路编辑
如果是谷歌和火狐等支持html5的浏览器,则可通过postMessage()方法即可跨域通信;如果是ie8之前等不支持html5的,则通过一个可以跨域的全局属性window.name,外部应用可以访问并修改iframe中的window.name。然后iframe中的页面每隔一段时间检查一下,如果window.name的值变化了则做出相应的事件响应。下面我们将这两种方法放在一起,这样不论在fiefox或者ie8等浏览器下都可以实现跨域提交,避开了浏览器的问题。
3. 解决方案编辑
3.1 模板设置
在需要进行填报的模板添加加载结束事件,我们这边选择新建一张模板CrossSubmit.cpt,直接在填报预览处添加加载结束事件,代码如下:
- function send(val){ sendMessage(val);
- }
- (function(win, doc){
- var ifr = win.parent;
- var cb = function(msg){
- eval(msg);
- };
- var sendMessage = function(){
- if(win.postMessage){
- if (win.addEventListener) {
- win.addEventListener("message",function(e){
- cb.call(win,e.data);
- },false);
- }else if(win.attachEvent) {
- win.attachEvent("onmessage",function(e){ cb.call(win,e.data);
- });
- }
- return function(data){
- ifr.postMessage(data,'*');
- };
- }else{
- var hash = '';
- setInterval(function(){
- if(win.name!==hash){
- hash = win.name;
- cb.call(win,hash);
- }
- },200);
- return function(data){
- ifr.name = data;
- };
- }
- }
- win.sendMessage = sendMessage();
- })(window, document);
3.2 提交页面设置
在本地新建test.html,此时test.html与我们报表模板是两个不同的域,在test.html中点"跨域提交"按钮,调用send("_g().writeReport()")则可以实现跨域提交。test.html的代码如下:
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>Untitled Document</title>
- </head>
- <script>
- window.name="aaaa";
- function f(){
- }
- </script>
- <body>
- <input type="button" name="aa" value="跨域提交" onclick="send('_g().writeReport()')"/>
- <iframe name="iframeA" id="iframeA" width="900" height="400" src="http://localhost:8075/WebReport/ReportServer?reportlet=CrossSubmit.cpt&op=write"></iframe>
- <script type="text/javascript">
- //document.getElementById('host').innerHTML = location.host;
- function send(msg){
- sendMessage(msg);
- }
- (function(win, doc){
- var ifr = doc.getElementById('iframeA').contentWindow;
- var cb = function(json){
- eval(json);
- };
- var sendMessage = function(){
- if(win.postMessage){
- if (win.addEventListener) {
- win.addEventListener("message",function(e){
- cb.call(win,e.data);
- },false);
- }else if(win.attachEvent) {
- win.attachEvent("onmessage",function(e){
- cb.call(win,e.data);
- });
- }
- return function(data){
- ifr.postMessage(data,'*');
- };
- }else{
- var hash = '';
- setInterval(function(){
- if (win.name !== hash) {
- hash = win.name;
- cb.call(win, hash);
- }
- }, 200);
- return function(data){
- ifr.name = data;
- };
- }
- };
- win.sendMessage = sendMessage();
- })(window, document);
- </script>
- </body>
- </html>
3.3 效果查看
由于使用的最简单的模板,即模板没有设计模板主体。
- IE8下:
- 谷歌下: