iframe重定向:从父页面跳出并让父页面重定向

前端开发 2026-07-09

我在我的网站上使用ASP插件来接受信用卡支付:
https://wordpress.org/plugins/stripe-payments/

这个插件有一个简短码(shortcode),会显示一个按钮,点击后会打开一个弹出框,内容来自这个URL:
https://webfor99.com/asp-payment-box/?product_id=4095
https://snipboard.io/rkLZEc.jpg
当交易被批准或拒绝时,它会重定向到相应的“感谢页面”或“错误页面”。

不过,我需要在页面上直接解决方案(而不是按钮)。所以我把这个URL直接嵌入一个iframe到页面中。效果很好,唯一的问题是不会跳转到相应的“感谢页面”或“错误页面”(iframe和父页面都没有跳转)。请查看截图:
https://snipboard.io/UPQ9aM.jpg

https://snipboard.io/S4as0G.jpg

我需要让iframe的跳转能够跳出iframe,进入父页面并让父页面跳转到相应的“感谢页面”或“错误页面”。

我咨询了插件的支持开发者,他们建议我:

如果你想用iframe的方式进行自定义(例如跨域),你可以尝试让父页面监听来自iframe的 postMessage,并执行 window.top.location.href = ...

于是我写了这段代码:

// Listen for messages from the iframe
window.addEventListener("message", function(event) {
    // SECURITY: Verify the origin of the message
     //if (event.origin !== "https://webfor99.com/asp-payment-box/?product_id=4095") 
         //return;

    // Check if the message indicates a success/redirect
    if (event.data && event.data.action === 'redirect') {
        alert(event.data)
        // Redirect the parent page to the new URL
        window.top.location.href = event.data.url;
    }
}, false);

然而,仍然无法让父页面跳转,我也已经没什么主意了。有没有多一个眼睛帮我看看?拜托,感谢!

解决方案

问题

你的父页面监听看起来没错,但问题很可能出在 iframe那边 —— iframe实际上并没有真正发送 postMessage。你只是监听,却没有发送消息。

完整解决方案

1.父页面(你的网站)

<script>
window.addEventListener("message", function(event) {
  // SECURITY: Verify the origin
  if (event.origin !== "https://webfor99.com") return;

  if (event.data && event.data.action === "redirect") {
    window.top.location.href = event.data.url;
  }
}, false);
</script>

<iframe id="payment-frame" src="https://webfor99.com/asp-payment-box/?product_id=4095"></iframe>

2. iFrame内部(支付页面 — 如果你有访问权限)

iframe页面在交易成功/失败后必须 发送 消息:

// After payment success/failure, call this:
function redirectParent(url) {
  window.parent.postMessage(
    { action: "redirect", url: url },
    "https://your-parent-domain.com" // target origin for security
  );
}

// Example usage:
// On success:
redirectParent("https://yoursite.com/thank-you");
// On error:
redirectParent("https://yoursite.com/error");

3.如果你没有iFrame来源的访问权限

由于这是一个第三方插件(webfor99.com),你很可能无法修改iframe。在这种情况下,改为在父页面轮询iframe的 URL:

const iframe = document.getElementById("payment-frame");

const checkIframeUrl = setInterval(function() {
  try {
    const iframeUrl = iframe.contentWindow.location.href;

    if (iframeUrl.includes("thank-you") || iframeUrl.includes("success")) {
      clearInterval(checkIframeUrl);
      window.location.href = "/thank-you";
    } else if (iframeUrl.includes("error") || iframeUrl.includes("denied")) {
      clearInterval(checkIframeUrl);
      window.location.href = "/error";
    }
  } catch (e) {
    // Cross-origin: can't read iframe URL — expected, just keep polling
  }
}, 500);

⚠️ 这种轮询方法只有在支付完成后iframe导航到同源URL时才有效。如果它在整个过程中都保持跨域,则浏览器的同源策略会阻止。

4.最佳的长期解决办法 — 请求插件支持 postMessage

由于插件开发者已经提到 postMessage,请他们把以下内容加入到他们的感谢页/错误页:

// They add this to their redirect pages:
if (window.self !== window.top) {
  window.parent.postMessage(
    { action: "redirect", url: window.location.href },
    "*" // or specify your domain
  );
}

快速调试提示:console.log("Message received:", event) 作为监听器的第一行。如果它从不打印日志,说明iframe根本没有发送消息——那就是根本原因。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章