跨域调用 JS

编辑
  • 文档创建者:文档助手1
  • 浏览次数:6570次
  • 编辑次数:16次
  • 最近更新:Kevin-s 于 2019-06-08
  • 1. 问题描述

    用户想要实现在自己的 OA 系统里点击按钮,就能触发我们的报表的提交事件。但是如果报表和他们的 OA 不在一个应用中,会存在 JS 跨域调用的权限问题,这个问题该如何解决呢?

    2. 实现思路

    如果是谷歌和火狐等支持 HTML5 的浏览器,则可通过 postMessage() 方法即可跨域通信;如果是 IE8 之前等不支持 HTML5 的,则通过一个可以跨域的全局属性 window.name,外部应用可以访问并修改 iframe 中的 window.name。然后 iframe 中的页面每隔一段时间检查一下,如果 window.name 的值变化了则做出相应的事件响应。下面我们将这两种方法放在一起,这样不论在 FireFox 或者 IE8 等浏览器下都可以实现跨域提交,避开了浏览器的问题。

    注:只能用于 H5 浏览器或者子域不同的情况,对于顶级域不同而且不支持 H5 的浏览器的时候就不行了,比如在 IE8 里面从 www.ttt.com --->org.aaa.com 就不能用。

    3. 解决方案

    这里使用提交_g().writeReport()做演示,其他js也都支持。

    3.1 模板设置

    在需要进行填报的模板添加加载结束事件,打开模板,%FR_HOME%\webapps\webroot\WEB-INF\reportlets\demo\form\填报可暂存.cpt,另存为%FR_HOME%\webapps\webroot\WEB-INF\reportlets\CrossSubmit.cpt,直接在填报预览处添加加载结束事件,代码如下:


    if(!window.a){
    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);
            window.a=1;
    }

    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/webroot/decision/view/report?viewlet=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 效果查看


    222



    附件列表


    主题: 部署集成
    标签: 暂无标签 编辑/添加标签
    如果您认为本文档还有待完善,请编辑

    文档内容仅供参考,如果你需要获取更多帮助,付费/准付费客户请咨询帆软技术支持
    关于技术问题,您还可以前往帆软社区,点击顶部搜索框旁边的提问按钮
    若您还有其他非技术类问题,可以联系帆软传说哥(qq:1745114201

    此页面有帮助吗?只是浏览 [ 去社区提问 ]