Django,Javascript:通过 javascript innerHtml 注入 DOM 的表单在提交时崩溃 google chrome 选项卡。在 IE 中工作

Posted

技术标签:

【中文标题】Django,Javascript:通过 javascript innerHtml 注入 DOM 的表单在提交时崩溃 google chrome 选项卡。在 IE 中工作【英文标题】:Django, Javascript: Form injected into DOM via javascript innerHtml crashes google chrome tab on submit. Works in IE 【发布时间】:2012-11-02 00:31:14 【问题描述】:

我编写了一个书签,它接收一个 Django 表单,并通过一个通过 javascript 创建的新 div 元素的 innerhtml 将它插入到 Dom 中,并附加到现有 html 文档的正文中。第一次提交是一个 ajax 请求(工作正常),如果表单由于未知用户而被 Django 拒绝,则提交函数与 ajax 解除绑定,并在没有 ajax 的情况下重新提交到弹出窗口以验证没有 CORS 的用户。该过程在 IE 中完美运行,但在单击提交按钮时会使 chrome 选项卡崩溃。

测试:我认为可能是最初的 ajax 提交导致了问题。但是,如果我在注入时使用没有 ajax 的相同进程,提交也会失败。如果我在注入完成后从浏览器复制 html 代码并创建一个新的 html 文档,然后在 chrome 中打开它,一切正常。此外,如果我在注入之前删除包含表单字段的 div,则提交按钮可以工作。这让我相信它与在现有页面上的 Dom 加载后注入表单有关。有没有办法在不刷新页面的情况下重新加载 Dom 或强制 innerHtml 在注入时在 Dom 中正确注册?

没有控制台错误,只是一个 aww,snap!显示此网页时出现问题。

要重现该问题,请按以下步骤操作:(我在 Windows 8 上使用 Chrome 版本 23.0.1271.64 m)(步骤 1) 转到图像网址:itsblackcurrent.com/wp- content/uploads/2012/07/what-hi.png(步骤 2) 进入 chrome 控制台并输入以下代码:

o = document.createElement("div");
o.setAttribute("id", "overlay");
o.innerHTML = '<div class="modal fade" id="new-pin"><div class="modal-header"><h3>New Pin</h3></div><form action="" enctype="multipart/form-data" method="get" id="ajaxform" name="pin_form" class="form-horizontal"><div class="modal-body"><div id="div_id_url" class="control-group"><label class="control-label" for="id_url">URL</label><div class="controls"><input type="text" name="url" id="id_url" /></div></div><div id="div_id_image" class="control-group"><label class="control-label" for="id_image">or Upload</label><div class="controls"><input type="file" name="image" id="id_image" /></div></div><div id="div_id_description" class="control-group"><label class="control-label" for="id_description">Description</label><div class="controls"><textarea id="id_description" rows="10" cols="40" name="description"></textarea></div></div><div id="div_id_tags" class="control-group"><label class="control-label" for="id_tags">Tags</label><div class="controls"><input type="text" name="tags" id="id_tags" /></div></div></div><div class="modal-footer"><div class="messageContainer"></div><button id="btnsubmit" type="submit" class="btn btn-primary">Submit</button><a id="cancel" onclick="removeOverlay()" data-toggle="modal" class="btn">Cancel</a></div></form></div>'; 
document.body.appendChild(o);

(第 3 步) 点击提交并查看 Chrome 崩溃!

(第 4 步) 如果在加载 DOM 之前加载完全相同的代码,它就可以工作。将以下内容粘贴到新的文本文档中并另存为 .html。

<body>
<script>
Copy and paste all the code from step 2 here
</script>
</body>

(第5步) 用chrome打开.html文件,提交不会崩溃。

【问题讨论】:

您是否在 Google 的问题跟踪器上报告了此问题? 我刚举报了。问题 226644。 我还必须做一些其他事情,涉及使用innerHTML 将 html 插入页面,并且它在 chrome 中崩溃了页面。不过,它不是一个图像页面,我只是插入一个带有一些文本的 div。奇怪... FWIW,我修复了今天发布的这个问题。 src.chromium.org/viewvc/blink?view=revision&revision=159667Chrome 应该不会再崩溃了,提交时 url 将具有表单值。 【参考方案1】:

我想出了如何防止在 chrome 中崩溃并且在 IE 中也可以使用!所以我们可以称之为跨浏览器的方式,在 dom 加载后注入表单,而不会导致 chrome 崩溃。

$('#form').submit(function () 
    formData = $("#form").serialize()
    window.location = "http:url.to.submitdata/?"+formData;
    return false;
);

首先,我们必须通过使用 jQuery 捕获 submit() 来创建自定义提交函数。然后序列化表单数据,并手动将表单数据附加到您要提交表单的url。最后,最重要的是 return false 停止正常的提交功能并防止 chrome 崩溃!

如果您按照说明复制我原来问题中的问题,您可以通过以下方式测试 Chrome 的解决方法:

(第 6 步) 完成我原来问题的第 1 步和第 2 步。(第 7 步) 在 chrome 控制台中输入以下代码:

s = document.createElement("script")
s.src = src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"
document.body.appendChild(s);
jQueryCheckLoad();

function jQueryCheckLoad() 
    if( window.$) 
        console.warn("jquery is ready");
        jqReady();
     else 
        window.setTimeout( jQueryCheckLoad, 10 );
    

function jqReady() 
    $( '#ajaxform' ).submit(function () 
        formData = $( "#ajaxform" ).serialize()
        window.location = "http://url.to.submitdata/?"+formData;
        return false;
    );

(第 8 步) 您将在控制台中看到“jQuery Ready”警告,然后单击提交并 BOOM!没有崩溃!

我们所做的只是通过创建一个返回 false 的自定义 jQuery submit() 来阻止正常的 submit()。首先我们注入 jQuery,然后使用 jQueryCheckLoad() 等待 jQuery 准备好。然后绑定我们的 jQuery submit()。

*如果有人知道导致 chrome 崩溃的原因,我仍然很想知道。最奇怪的部分是,当我第一次解绑并提交表单时,它在大约 2 小时的测试中非常一致地工作,然后神秘地开始不断地崩溃。我修改了注入顺序并且没有清除书签上的缓存的可能性很小,当我这样做时它开始崩溃。这让我相信有一种方法可以在不刷新页面的情况下成功地重新加载 DOM。

【讨论】:

【参考方案2】:

这是一个 javascript 小书签,它会使您的 chrome 浏览器崩溃。

javascript:var i = 0; while (i < 1)  window.location.reload(true); i = i - 1; ;

也只有普通的 javascript 形式(基本上是一样的,但没有 javascript: 在开头,它有单独的行)。

var i = 0;
while (i < 1) 
window.location.reload(true);
i = i - 1;

这是一个 url,当你在浏览器中打开它时,它会使用它来崩溃你的浏览器。

https://codehs.com/editor/html/4767743/2616125/index.html

【讨论】:

以上是关于Django,Javascript:通过 javascript innerHtml 注入 DOM 的表单在提交时崩溃 google chrome 选项卡。在 IE 中工作的主要内容,如果未能解决你的问题,请参考以下文章

Django,Javascript:通过 javascript innerHtml 注入 DOM 的表单在提交时崩溃 google chrome 选项卡。在 IE 中工作

如何通过 javascript 从管理页面检索 Django 模型 ID

通过(ajax/javascript)发布到 django 视图打印空查询集

通过 JavaScript 在 Django 中显示图像

如何通过 HTML 中的 JavaScript 在 Django 中保存模型实例

通过使用javascript单击按钮动态添加django表单