使用 Angular 检测 Iframe 中的 PHP 页面重新加载

Temp mail SuperHeros
使用 Angular 检测 Iframe 中的 PHP 页面重新加载
使用 Angular 检测 Iframe 中的 PHP 页面重新加载

处理 Angular 应用程序中的 Iframe 重新加载

在现代 Web 开发中,通过 iframe 将 PHP 页面等外部应用程序嵌入到 Angular 项目中是一种常见的方法。然而,当尝试监视 iframe 中的事件或页面重新加载时,它会带来挑战,特别是当您无权访问 PHP 项目的代码时。

当您需要在刷新 iframe 内容时在 Angular 应用程序中显示加载微调器时,就会出现这样的挑战之一。由于您无法修改 PHP 代码,因此检测 iframe 内容的重新加载或更改变得很棘手。关键是找到一种从 JavaScript 端跟踪 iframe 变化的方法。

许多开发人员想知道是否可以将脚本注入到 iframe 中来侦听 HTTP 请求或重新加载等事件,特别是如果 iframe 源自您无法直接控制代码的项目。这可以通过 Angular 应用程序中的 JavaScript 来完成。

在本文中,我们将探讨检测 iframe 内的 PHP 页面何时重新加载的可能解决方案,以及如何实现加载微调器以响应此类更改。尽管您无法访问 PHP 代码本身,但 JavaScript 可以提供创造性的解决方案。

命令 使用示例
contentWindow 访问 iframe 的窗口对象,允许您从父窗口操作脚本或将脚本注入到 iframe 的 DOM 中。示例: const iframe = document.querySelector("iframe").contentWindow;
addEventListener("load") 注册一个事件侦听器,该事件侦听器在 iframe 完成加载或重新加载时触发。对于跟踪 iframe 内容何时发生变化很有用。示例: iframe.addEventListener("load", function() {...});
postMessage 启用 iframe 与其父窗口之间的安全通信,允许来回传递消息。示例:parent.postMessage("iframeReloaded", "*");
XMLHttpRequest.prototype.open 覆盖 XMLHttpRequest 的默认行为以检测何时发出网络请求。有助于在 iframe 中触发 HTTP 请求时注入自定义逻辑。示例: XMLHttpRequest.prototype.open = function() {...};
fetch 拦截用于发出 HTTP 请求的 JavaScript Fetch API,以在网络请求正在进行时显示微调器。示例:window.fetch = function() {...};
createElement 在 DOM 中动态创建新的 HTML 元素。这用于将脚本或其他元素注入 iframe 的文档中。示例: const script = iframe.document.createElement('script');
appendChild 将新节点(例如脚本或 div)添加到 iframe 的 DOM 树,从而允许将 JavaScript 注入到 iframe 中。示例: iframe.document.body.appendChild(script);
window.onload iframe 页面完全加载后执行函数,从而在 iframe 完成重新加载时启用通知。示例: window.onload = function() {...};
style.display 通过更改 HTML 元素(如微调器)的 CSS 显示属性来操纵 HTML 元素的可见性。对于在页面加载期间切换微调器可见性很有用。示例: document.getElementById("spinner").style.display = "block";

探索 Angular 中检测 Iframe 重新加载的解决方案

在第一个脚本中,关键思想是监听 加载 iframe 的事件。每次 iframe 的内容更改或重新加载时都会触发 load 事件。通过使用此事件,我们可以检测 iframe 内的 PHP 页面何时刷新。最初,通过调用函数显示加载旋转器 显示旋转器。一旦 iframe 内容完全加载, 隐藏旋转器 调用函数来隐藏微调器。这种方法非常有效,因为它不需要访问 PHP 代码,只依赖于 iframe 的状态。

第二种解决方案采用更高级的方法,将 JavaScript 直接注入 iframe 中。通过访问 iframe 内容窗口,我们可以动态创建脚本元素并将其插入到 iframe 的 DOM 中。该脚本使用 iframe 内的 PHP 页面发起的任何 HTTP 请求 XMLHttp请求获取API。这里的目标是监视 iframe 内的网络活动,并在发生任何此类活动时显示加载微调器。此方法通过跟踪发出 HTTP 请求的确切时刻来提供更精细的控制。

第三种方法利用 发布消息 API,允许 iframe 和父 Angular 应用程序之间进行通信。在这种情况下,iframe 每当完成加载时都会向父级发送一条消息。父窗口侦听这些消息并相应地显示或隐藏微调器。使用 postMessage 的优点是它是一种在窗口之间交换信息的安全方式,即使您无权访问 iframe 的内部代码也是如此。它非常适合父级 iframe 和 iframe 来自不同域的跨源 iframe。

这些解决方案中的每一个都有其优点,方法的选择取决于您需要的控制级别和 iframe 的行为。加载事件侦听器很简单,但仅适用于检测完全重新加载。将脚本注入 iframe 可以更详细地了解其活动,但需要 iframe 允许脚本插入。最后, 发布消息 方法是处理跨域通信的强大解决方案,并且可以向父级通知特定的 iframe 事件。这些方法提供了灵活的方法来处理 iframe 状态更改,而无需直接访问 PHP 代码。

解决方案 1:使用“load”事件监控 iframe 重新加载

该解决方案使用 JavaScript 监听 iframe 的“load”事件,检测 iframe 何时重新加载或更改内容。

// Select the iframe element by its ID or query selector
const iframe = document.getElementById("myIframe");
// Function to display the spinner
function showSpinner() {
  document.getElementById("spinner").style.display = "block";
}
// Function to hide the spinner
function hideSpinner() {
  document.getElementById("spinner").style.display = "none";
}
// Add event listener for the iframe's load event
iframe.addEventListener("load", function() {
  hideSpinner();
});
// Display the spinner initially before iframe reload completes
showSpinner();
// HTML: Loading spinner (CSS or image-based)
<div id="spinner" style="display: none;">Loading...</div>

解决方案2:将JavaScript注入iframe以跟踪网络请求

此方法将脚本注入 iframe 中以检测任何 HTTP 请求或重新加载,当您需要跟踪页内更改或从 iframe 内重新加载时非常有用。

// Access the iframe's content window
const iframe = document.querySelector("iframe").contentWindow;
// Create a script to inject into the iframe
const script = iframe.document.createElement('script');
// JavaScript to track network requests
script.textContent = `
  (function() {
    const oldFetch = window.fetch;
    window.fetch = function() {
      document.querySelector('#spinner').style.display = 'block';
      return oldFetch.apply(this, arguments);
    };
    const oldXHR = window.XMLHttpRequest;
    XMLHttpRequest.prototype.open = function() {
      document.querySelector('#spinner').style.display = 'block';
      oldXHR.open.apply(this, arguments);
    };
  })();`;
// Append the script to the iframe's document
iframe.document.body.appendChild(script);

方案3:使用postMessage在iframe和parent之间进行通信

此方法使用“postMessage”API 在 iframe 和父窗口之间进行通信,通知父窗口 iframe 中的任何重新加载或更改。

// Parent script (Angular application)
const iframe = document.querySelector("iframe");
// Listen for messages from the iframe
window.addEventListener("message", function(event) {
  if (event.data === "iframeReloaded") {
    document.getElementById("spinner").style.display = "none";
  }
});
// Iframe script to post a message on reload
const iframeScript = document.createElement('script');
iframeScript.textContent = `
  window.onload = function() {
    parent.postMessage("iframeReloaded", "*");
  };`;
// Inject the script into the iframe
iframe.contentWindow.document.body.appendChild(iframeScript);

监控 Angular 中 iframe 变化的高级技术

检测 iframe 中变化的另一个有趣的技术是使用 变异观察者 API。此 API 允许您监视 DOM 树中的更改,例如添加或删除新节点的时间。虽然这不会在 PHP 页面重新加载时直接通知您,但它可以帮助检测 iframe 内容的更改。例如,如果 iframe 中的某些元素在重新加载后被替换或更新,则 变异观察者 可以捕捉这些变化并相应地触发旋转器。

此外,利用浏览器事件,例如 卸载前 或者 卸下 可以帮助检测 iframe 何时即将重新加载。当页面正在卸载或启动离开当前页面的导航时,将触发这些事件。通过向 iframe 内的这些事件添加事件侦听器,您可以通知父窗口即将发生重新加载,从而确保微调器在正确的时间显示。此方法与其他方法结合使用时效果最佳,可提供全面的解决方案。

最后,您可以考虑使用 iframe 轮询作为检查更改的方法。在此方法中,父 Angular 应用程序会定期检查 内嵌框架 URL 或 iframe 中的其他特定元素,以确定内容是否已更改或重新加载。虽然这种方法的效率可能较低,尤其是在性能方面,但当其他方法不可行时,它是一个后备选项。缺点是轮询可能无法检测所有页内更改,但对于特定场景仍然有用。

有关监控 Iframe 重新加载的常见问题

  1. 如何检测 iframe 重新加载?
  2. 您可以使用 addEventListener("load") 用于检测 iframe 何时重新加载或其内容更改的事件。
  3. 是否可以在iframe中监控网络请求?
  4. 是的,通过将脚本注入 iframe,您可以覆盖 fetchXMLHttpRequest.prototype.open 跟踪 HTTP 请求的方法。
  5. 我可以使用 postMessage 在 iframe 和父窗口之间进行通信吗?
  6. 是的, postMessage API 允许 iframe 与其父窗口之间进行安全通信,从而实现它们之间的消息传递。
  7. 如果我无法将 JavaScript 注入 iframe 该怎么办?
  8. 如果您无权注入 JavaScript,请使用 MutationObserver API 或 postMessage iframe 中的方法(如果支持的话)是潜在的替代方案。
  9. MutationObserver 如何帮助检测 iframe 更改?
  10. MutationObserver API 监视 DOM 中的变化,当 iframe 中的元素在重新加载后发生变化时,它可以向您发出警报。

关于在 Angular 中监控 Iframe 重新加载的最终想法

通过创造性的 JavaScript 解决方案,可以在不直接访问底层 PHP 代码的情况下监控 iframe 重新加载。无论是使用事件侦听器、注入脚本还是 postMessage API,开发人员都可以选择确保其 Angular 应用程序保持响应能力。

每种方法都有其优点,具体取决于项目的复杂性和对 iframe 的控制。通过利用适合您的具体情况的最佳解决方案,您可以在 iframe 内容更改期间通过可靠的微调器通知提供更好的用户体验。

参考文献和外部资源
  1. 有关监视 iframe 事件和跨域通信的详细文档可以在以下位置找到: MDN 网络文档 - postMessage API
  2. 有关使用 MutationObserver 进行 DOM 更改的更多信息,请参阅 MDN 网络文档 - MutationObserver
  3. 要探索将 JavaScript 注入 iframe 的技术,请查看此资源 StackOverflow - 将 JavaScript 注入 iframe