交互后如何获取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&amp;cell_id=ESICAS23B_ESICAS23&amp;refresh=5s&amp;orgId=1&amp;panelId=4&amp;from=1555045266010&amp;to=1555168469864&amp;var-cell_id=ESICAS23B_ESICAS23&amp;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");
&lt;iframe width="400" height="244" src="https://wooden-utensil.github.io/linkingSite1/" onload="iframeLoad(this)" frameBorder="0"&gt;&lt;/iframe&gt; &lt;!-- linkingSite1 contains a link (a href) that links to linkingSite2, and vice versa --&gt;

【讨论】:

谢谢,刷新 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的主要内容,如果未能解决你的问题,请参考以下文章

【新手】jquery iframe的src动态赋值问题

html获取iframe内的数据

iframe获得内容,如何获得页面的中间部分?

jquery 如何实现iframe页面的切换??

jquery判断iframe元素是不是在可视范围如果不是则滑动到可视区域

jquery如何获取页面中引入iframe网页的内容