将 javascript 注入 iframe

Injecting javascript into an iframe

我正在使用一个页面,其中包含一个包含表单的 iframe。

我无权修改“源代码”,但可以通过 Google 标签管理器注入代码。

我可以使用以下方法轻松填充其中一个表单字段:

var iframe = document.getElementById('my_iframe');
var iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
var amountInput = iframeDocument.getElementById("transaction_amount");
amountInput.setAttribute("value", "100");

但是,我也想更改表单提交按钮的 onclick 方法,但是 运行 遇到了一些问题。最初我尝试过这样的事情:

function validate_form() {
  if (amountInput > 100) {
    alert("No chance!");
    return false;
  }
  return true;
}
iframeDocument.getElementById("submit_button").setAttribute("onclick","return validate_form();");

我认为这些问题是从主页调用我的“注入”,但从 iframe 中调用注入ED 代码的结果。第一个问题是提交按钮找不到函数...

为了修复我尝试过的问题:

frames["my_iframe"].window.validate_form = function() { 
  if (amountInput > 100) {
    alert("No chance!");
    return false;
  }
  return true;
}
iframeDocument.getElementById("submit_button").setAttribute("onclick","return validate_form();");

现在它触发了,但无法访问 amountInput...再次怀疑是因为它是在主页范围内定义的,而不是在 iframe 内定义的。

然后我通过将原始注入脚本调整为类似以下内容来修复此问题:

var iframe = document.getElementById('my_iframe');
var iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
var amountInput = iframeDocument.getElementById("transaction_amount");
amountInput.setAttribute("value", "100");
frames["giftCard_iframe"].window.amountInput = amountInput;

但这一切看起来非常混乱,难以理解。是否有 simpler/more 标准方法?

您可以使用注入到 iframe 脚本来做同样的事情:

var iframe = document.getElementById('my_iframe');
var iframeDocument = iframe.contentDocument || iframe.contentWindow.document;

var scriptSource = `
    window.addEventListener('DOMContentLoaded', function() {
        var form = document.getElementById('form'); // change to the actual form selector
        var input = document.getElementById('transaction_amount');
        input.value = 100;

        form.addEventListener('submit', function (ev) {
            if (Number(input.value) > 100) {
                alert('No chance');
                ev.preventDefault();
            }
        });
    });
`;
var script = iframeDocument.createElement("script");
var source = iframeDocument.createTextNode(scriptSource);
script.appendChild(source);
iframeDocument.body.appendChild(script);

我添加了等待 DOMContentLoaded 事件,但如果您确定 iframe 的 DOM 在您要注入此脚本时已准备就绪,则可以省略 addEventListener('DOMContentLoaded', ...) 包装。

我还用表单的 submit 事件侦听器更改了 onclick 内联属性。虽然您可以通过多种方式提交表单:在表单的一个字段中点击 enter,然后按 Tab 键导航至 submit 按钮,然后按键盘上的 spaceentersubmit 事件是最终目的地,您可以在提交前验证表单并在出现问题时阻止它。当然,您必须向表单分配一些 id 或任何其他属性才能向其添加事件侦听器。

实际上我最终采用了不同的方法。

意识到我可以从 iFrame 中引用 parent.function(),而不是将脚本注入 iFrame。

这解决了无法访问变量和调用函数的范围的问题。