历史版本12 :跨域调用 JS 返回文档
编辑时间:
内容长度:图片数:目录数:
修改原因:
1. 问题描述编辑
用户想要实现在自己的OA系统里点击按钮,就能触发我们的报表的提交事件。但是如果报表和他们的OA不在一个应用中,会存在js跨域调用的权限问题,这个问题该如何解决呢?
2. 实现思路编辑
如果是谷歌和火狐等支持html5的浏览器,则可通过postMessage()方法即可跨域通信;如果是ie8之前等不支持html5的,则通过一个可以跨域的全局属性window.name,外部应用可以访问并修改iframe中的window.name。然后iframe中的页面每隔一段时间检查一下,如果window.name的值变化了则做出相应的事件响应。下面我们将这两种方法放在一起,这样不论在fiefox或者ie8等浏览器下都可以实现跨域提交,避开了浏览器的问题。
注:只能用于H5浏览器或者子域不同的情况,对于顶级域不同而且不支持H5的浏览器的时候就不行了,比如在IE8里面从www.ttt.com --->org.aaa.com就不能用。
3. 解决方案编辑
3.1 模板设置
在需要进行填报的模板添加加载结束事件,打开模板,%FR_HOME%\WebReport\WEB-INF\reportlets\demo\form\Customer.cpt,另存为%FR_HOME%\WebReport\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/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 效果查看