如何让跨域父页面iframe自适应SAPUI5子页面完整高度?
跨域嵌入SAPUI5页面到iframe并自适应完整高度的解决方案
问题背景
需要将SAPUI 1.120版本的网站嵌入到不同服务器的父页面iframe中,实现iframe自适应子页面的完整高度。最初尝试仅在父页面计算高度,但受跨域DOM访问策略限制失败,且无法修改该策略。以下是尝试的方案及最终解决办法。
尝试的方案
方案二:通用页面适配方案(非SAPUI5有效,SAPUI5失效)
通过postMessage传递高度,但在SAPUI5页面中获取到的高度始终是当前iframe的高度,无法获取完整页面高度。
父页面代码:
<script> window.addEventListener('message', receiveMessage, false); function receiveMessage(size){ resizeIFrameToFitContent(size.data); } function resizeIFrameToFitContent(size){ document.getElementById("exampleFrame").style.height = size; } </script>
子页面代码:
function postPageSize(){ size = window.document.body.scrollHeight + "px"; window.parent.postMessage(size, '*'); }
方案三:定时器动态调整(跨域报错)
尝试用定时器定期获取子页面高度,但触发跨域权限错误:Uncaught DOMException: Permission denied to access property "document" on cross-origin object,无法解决。
父页面代码:
<script> setInterval(function(){ var pageHeight = document.getElementById("exampleFrame").contentWindow.document.body.offsetHeight; }, 1000) </script>
方案四:自定义元素高度计算(旧版SAP有效,新版失效)
通过定位SAPUI5页面内的特定元素计算高度,但在目标版本中获取的仍是当前iframe高度。
父页面代码:
<script> window.addEventListener('message', e=>{if (e.origin=="http://localhost"){ var iFr = document.getElementById("exampleFrame") if (iFr && iFr.style.height != e.data) iFr.style.height = e.data }}) </script> <iframe src="http://localhost/path/to/page" id="exampleFrame" style="height:500px"></iframe>
子页面代码:
function ensureIFrameResizingFor(MainCont){ setInterval(function(){ var pgId = MainCont.getCurrentPage().getId() //MainCont 为承载页面的App或Navigation容器 var hFrm = 0, hHdr = 0 var hdr = document.querySelector("#" + pgId + " .sapMPageHeader") if (hdr) hHdr = parseInt("0" + getComputedStyle(hdr).getPropertyValue("height")) var frm = document.querySelector("#" + pgId + " .sapUiSimpleForm") if (!frm){ hHdr = 3*hHdr frm = document.querySelector("#" + pgId + " .sapUiTableVSbContent") //列表页面降级处理 if (!frm) frm = document.querySelector("#" + pgId + " .sapMListTblCnt") } if (frm) hFrm = parseInt("0" + getComputedStyle(frm).getPropertyValue("height")) //console.log(hFrm, hHdr) if (hFrm) top.postMessage((hFrm + hHdr + 18) + "px", PostMsg_CallbackURL) }, 500) }
最终解决方案
通过定位SAPUI5页面中带滚动条的元素(类名为sapMPageEnableScrolling)获取scrollHeight,并结合定时器定期执行(适配页面元素动态变化),再通过postMessage将高度传递给父页面。
子页面核心函数:
function sendSizeToParent(){ const scrollContainer = document.getElementsByClassName("sapMPageEnableScrolling")[0]; if(scrollContainer?.scrollHeight != null){ const height = scrollContainer.scrollHeight; window.parent?.postMessage(height, '*'); } }
补充说明
- 需在SAPUI5页面加载完成后调用
sendSizeToParent,并通过定时器(如setInterval(sendSizeToParent, 500))定期执行,适配页面内容动态更新的场景。 - 父页面仍可使用方案二或方案四中的
message监听逻辑接收高度,进而调整iframe高度。
内容的提问来源于stack exchange,提问作者Annika
相关产品推荐
相关产品推荐

