交互后如何获取iframe的刷新src
Posted
技术标签:
【中文标题】交互后如何获取iframe的刷新src【英文标题】:How to get iframe's refreshed src after interacting 【发布时间】:2019-10-23 01:55:52 【问题描述】:我有一个与 Grafana 图形链接的 iframe 标记,它支持交互(通过单击/双击 iframe 在 x 轴上放大/缩小)。
当我在新选项卡上打开 iframe src 的 url 时,我可以与图形交互,并看到我的浏览器的 url 参数不断刷新新的 from/to 值(这表示图形的 x 轴的范围)。不幸的是,当它在 iframe 上时,在任何情况下我都看不到“src”属性的任何变化。我需要将 url 参数更改应用于正在显示的其他图表(同步它们)。
我该如何解决这种情况?
我在 Angular 的 component.html 上的 iframe:
<iframe [src]="url_grafana_primary" frameborder="0"></iframe>
渲染后的 iframe:
<iframe _ngcontent-c8="" frameborder="0" src="http://146.250.180.213/grafana/dashboard-solo/script/script_graph.js?scenario_id=rrc_succ_rate&cell_id=ESICAS23B_ESICAS23&refresh=5s&orgId=1&panelId=4&from=1555045266010&to=1555168469864&var-cell_id=ESICAS23B_ESICAS23&var-scenario_id=ESICAS23B_ESICAS23"></iframe>
一些截图:
更改前:https://i.imgur.com/6M5JoHX.png 修改后:https://i.imgur.com/MN0KIha.png您可以看到 src 在两种情况下都保持相同的值。
【问题讨论】:
【参考方案1】:src 的属性没有改变,但location
对象的行为应该与 grafana 在 iframe 之外时的行为相同。
你有两个选择,
-
如果 grafana 的 frame 和它的 parent 来自同一个源,您可以使用
iframe.contentWindow.location.href
访问 location 对象。
如果它们的来源不同,你需要在框架和它的父框架之间进行通信,你可以使用postMessage。
查看此示例:https://robertnyman.com/html5/postMessage/postMessage.html
【讨论】:
能否举个例子说明我如何在 Typescript 上使用 postMessage? 它与 Typescript 无关,它是一个浏览器 API。你在 MDN 中有例子。 我添加了一个例子 好的...所以我的理解是,'postMessage' 机制只有在目标 url 准备好接收此消息时才有效,对吧?如果是这样,据我所知,我无法准备 Grafana(iframe 的服务器)来响应此消息,因为我没有开发它。请尽可能纠正我。 另外,有一条随机消息,我收到此错误:“无法在 'DOMWindow' 上执行 'postMessage':提供的目标原点 ('146.250.180.213') 与收件人窗口的原点不匹配 ( 'localhost:4201')。”【参考方案2】:您可以检测到onload
事件,但要获取 URL,您必须存储 cookie 或 localStorage
。
var firstTimeLoad = true; // Because the function will call on the initial page
function iframeLoad(iframe)
if (firstTimeLoad)
firstTimeLoad = false;
return;
alert("New page load");
<iframe width="400" height="244" src="https://wooden-utensil.github.io/linkingSite1/" onload="iframeLoad(this)" frameBorder="0"></iframe> <!-- linkingSite1 contains a link (a href) that links to linkingSite2, and vice versa -->
【讨论】:
谢谢,刷新 iframe 内容时不会调用 'onload' 下的代码。尝试使用`` ``它没有工作。 @DenisCandido 我右键单击 iframe 并单击“重新加载框架”,然后出现警告框。我不知道为什么它没有出现在你面前? Grafana iframe 的工作方式不同。您可以与之交互,但它不会“刷新”。它确实会更新其值,但不会触发公共刷新。我不知道它是如何工作的,Grafana 社区也没有帮助我。【参考方案3】:您只需要将 iframe 的 src 设置为相同的旧 src。您可能需要添加一个带有随机数(如时间戳)的查询字符串变量以避免缓存问题。
function refresh()
var iframe = document.getElementById('myframe');
iframe.src = iframe.src;
iframe
width:100%;
height:300px;
<p>
<button onclick="refresh()">Refresh</button>
</p>
<iframe id="myframe" src="https://www.chartjs.org/samples/latest/charts/line/basic.html" frameborder="0"></iframe>
【讨论】:
【参考方案4】:如果您不是 iframe 中内容的所有者,您将无能为力。您可以做的最好的事情是有一个循环 (setInterval),它将根据您看到的最后一个值检查该值。
<iframe #graph></iframe>
@ViewChild('graph', static: true ) graph!: ElementRef<HTMLIFrameElement>;
private srcWatcher = new Observable(observer =>
const interval = setInterval(() =>
observer.next(this.graph && this.graph.nativeElement && this.graph.nativeElement.src);
, 10);
return () => clearInterval(interval);
).pipe(
distinctUntilChanged(),
);
有了这个 observable,你现在可以对它的任何变化做出反应。
注意:如果间隔超时应该很低,我还建议 observable 应该在 zoneJS 之外运行。否则 Angular 会在每个时间间隔运行全局变化检测。全局我的意思是,它会检查整个应用程序的所有子树,使用默认的更改检测策略。
【讨论】:
不幸的是,没用。 srcWatcher 从不触发。 @DenisCandido 很抱歉,这是不可能的,这是一项安全功能。以上是关于交互后如何获取iframe的刷新src的主要内容,如果未能解决你的问题,请参考以下文章