【问题标题】:Form onsubmit in dynamic iframe do not get triggered动态 iframe 中的表单提交不会被触发
【发布时间】:2019-04-05 15:56:03
【问题描述】:

更新

问题不在于 iframe,问题在于发布 json 的 onsubmit 函数未提交表单。目标是动态创建一个 iframe,该 iframe 使用表单发布重定向到具有上述脚本标记的 json 内容的另一个 URL。

原创

我在示例网站上有以下内容:

<script data-dashboard="true" type="application/json">
    {
    "title":"Serverless Identity"
    }
</script>
<script type="text/javascript">
    let dashboardConfiguration = document.querySelector("script[data-dashboard=\"true\"]");
    if (dashboardConfiguration) {
        let iframe = document.createElement("iframe");
        let model = JSON.stringify(JSON.parse(dashboardConfiguration.innerHTML.trim()));
    
        document.body.appendChild(iframe);

        var doc = iframe.contentWindow.document;
        doc.open()
        doc.writeln(`<form id="form" action="https://localhost:44338/dashboard/" method="POST" target="_self"></form>`)
        doc.close();


        iframe.onload = () => {
           

            let form = doc.getElementById("form");
             
            form.addEventListener("submit", (e) => {
                console.log(model);
                e.preventDefault();
                // construct an HTTP request
                var xhr = new XMLHttpRequest();
                xhr.open(form.method, form.action, true);
                xhr.setRequestHeader('content-type', 'application/json; charset=UTF-8');
                 
                // send the collected data as JSON
                xhr.send(model);

                xhr.onloadend = function () {
                    // done
                };
            });
            form.submit();


        }
    };

</script>

我也尝试了onsubmit,结果与正常提交相同。

【问题讨论】:

  • IFRAME 的 onload 事件不可靠。此外,您不应将箭头函数用于事件侦听器 - 尝试将 onsubmit 与普通函数一起使用(类似于 &lt;form onsubmit="return ajaxSubmit(event)"&gt;,然后在此函数中返回 false
  • 您的建议没有任何改变。
  • 所以您正在创建一个表单,向该表单添加一个提交处理程序,从脚本提交该表单,然后您在提交处理程序中发出一个 AJAX 请求。为什么?为什么不直接发出 AJAX 请求并完成它,这个表单的目的是什么……?
  • 没有表单就不能重定向页面吗?

标签: javascript


【解决方案1】:

不可能,

根据规范,当使用 form.submit() 时,任何 onsubmit 处理程序都不会触发。

我使用了一种不同的方法,即使用表单编码值发送普通表单提交,其中一个隐藏字段中的空洞有效负载,并在服务器端对其进行反序列化。

【讨论】:

    【解决方案2】:

    当你创建了 iframe 然后它被加载然后你绑定 onload 而不是当 iframe 被附加到 body 时你应该在 body 上使用 DOMNodeInserted 事件

    let iframe = document.createElement("iframe");
            let model = JSON.stringify(JSON.parse(dashboardConfiguration.innerHTML.trim()));
    document.body.addEventListener("DOMNodeInserted", function (ev) {
    //write your logic here
    });
            document.body.appendChild(iframe);
    
            var doc = iframe.contentWindow.document;
    

    【讨论】:

    【解决方案3】:

    删除iframe.onload = () =&gt; { }。检查 chrome network 选项卡。表单 url https://localhost:44338/dashboard/ 被触发。

    <script data-dashboard="true" type="application/json">
        {
        "title":"Serverless Identity"
        }
    </script>
    <script type="text/javascript">
        let dashboardConfiguration = document.querySelector("script[data-dashboard=\"true\"]");
        if (dashboardConfiguration) {
            let iframe = document.createElement("iframe");
            let model = JSON.stringify(JSON.parse(dashboardConfiguration.innerHTML.trim()));
    
            document.body.appendChild(iframe);
    
            var doc = iframe.contentWindow.document;
            doc.open()
            doc.writeln(`<form id="form" action="https://localhost:44338/dashboard/" method="POST" target="_self"></form>`)
            doc.close();
    
            let form = doc.getElementById("form");
    
            form.addEventListener("submit", (e) => {
                console.log(model);
                e.preventDefault();
                // construct an HTTP request
                var xhr = new XMLHttpRequest();
                xhr.open(form.method, form.action, true);
                xhr.setRequestHeader('content-type', 'application/json; charset=UTF-8');
    
                // send the collected data as JSON
                xhr.send(model);
    
                xhr.onloadend = function () {
                    // done
                };
            });
            form.submit();
        }
    

    【讨论】:

    • 是的,它的触发器,但使用普通表单提交,而不是我想要的 xhr json 帖子。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-12
    • 2014-11-07
    • 1970-01-01
    • 2013-06-25
    • 1970-01-01
    相关资源
    最近更新 更多