浏览器原生自动完成对于动态生成表单(使用AJAX处理)的支持

20

我正在动态生成一个表单。为了简单起见,假设它是一个带有电子邮件/密码的登录表单。表单被提交,但在提交时它会触发处理实际登录的AJAX请求,且通过e.preventDefault()取消提交事件。

我使用e.preventDefault()来取消表单的默认操作,即“转到'action'中的页面”,但这似乎也会取消浏览器的自动完成检测。

我认为要使原生自动完成功能工作,需要满足以下几个条件:

  • 你的输入字段type="text"必须有一个name
  • 表单必须被提交<-- 在我的情况下,这并没有真正发生

我的分析正确吗?是否有任何方法使自动完成在此情况下工作?


为了避免追随者们的干扰: 我不寻求任何涉及jQuery[插入您的框架]的解决方案,我想要使用浏览器自带的自动完成功能。我没有想要自动完成的单词列表。

3个回答

14

好的,我找到了一种复杂的方法来做到这一点:

以下是Javascript代码:

function ajaxit() {
    var iFrameWindow = document.getElementById("myframe").contentWindow;
    iFrameWindow.document.body.appendChild( document.getElementById("myform").cloneNode(true));   
    var frameForm = iFrameWindow.document.getElementById("myform");
    frameForm.onsubmit = null;
    frameForm.submit();
    return false;
}
这是HTML代码:

Here is the html:

<form id="myform" onsubmit="return ajaxit();" autocomplete="on">
    <input id="foo" name="foo"/> 
    <input type="submit" />
</form>
<iframe id="myframe" src=""></iframe> <!-- you'll want this hidden -->

点击提交按钮将运行ajaxit()方法。该方法会在iframe中创建相同的表单,并将其提交到服务器。您可以利用该提交来执行您的服务器请求,也可以执行单独的ajax请求并忽略iframe。

我知道这很丑,但它确实有效。

编辑:这里有一个jsbin可供测试。


聪明,我喜欢。我不知道为什么我没有想到这个:P 我原本以为 iframe 不起作用,但显然它可以! - Halcyon
实际上有两种不同的情况:使用 AJAX 提交的表单和动态生成的表单(很可能也是使用 AJAX 提交)。jsbin 示例仅涵盖第一种情况。 - smhg
请您详细说明正在发生什么?与直接提交表单相比,在iframe内提交表单有什么好处?我认为我们要解决的问题是如何使用AJAX提交表单,而不是使用正常的表单提交机制。在我的情况下,我必须提交JSON。服务器将不接受正常的表单编码(例如application/x-www-form-urlencoded)。 - Gili
Gili,那不是问题所在。问题在于如果你使用AJAX提交它,那么浏览器将不会记住未来自动完成的值。这个问题并不涉及使用ajax提交表单。它假设您已经这样做了,并希望浏览器将值存储在其自动完成历史记录中。 - Daniel Moses
有人在大型网站的生产环境中使用过这个方法吗?使用这种方法有什么需要注意的地方吗?作为一个安全措施,如果您要提交敏感数据,请记得在表单上添加一个不是get值的方法属性! - alexrogers

11

DMoses的解决方案启发了我的解决方案,但两者有显著区别,所以我认为自己想出一个解决方案是个好主意。奖励归DMoses :P

DMoses的解决方案将表单移动(或复制)到iframe中,然后提交它。你想这样做的原因是为了使你的“父”表单不重新加载。有一个更简单的解决方案:让表单提交到iframe中。这完全相同,而且您不必复制任何节点。

这一步也是完全可重复的。唯一的缺点是你不能控制何时添加自动完成条目。您可能只想添加有效 条目,但至少此情况完美地模拟了如果没有使用ajax,普通表单的行为方式。如果您想控制要添加到自动完成中的内容,请使用DMoses的解决方案,复制表单并在iframe中提交。

对我来说,这已经足够了:

<form onsubmit="return ajaxit();" autocomplete="on" target="the_iframe">
    <input id="foo" name="foo"/> 
    <input type="submit" />
</form>
<iframe id="the_iframe" name="the_iframe" src="javascript:false"></iframe> <!-- you'll want this hidden -->

最棒的一点是:不需要额外的JavaScript就可以使其工作!(除了为表单生成一个唯一的id/name,但这非常简单)。

jsFiddle: http://jsfiddle.net/KzF6s/13/


1
我认为这并不重要。我发布的页面(javascript:false)不是一个真正的页面,仅仅为了让它工作而有一个总是返回500的空闲页面是可疑的。 - Halcyon
我认为你是正确的。这个解决方案对我也不再起作用了。 - Halcyon
我错了:event.preventDefault() 不应该在那里。这是一个正确的 fiddle:http://jsfiddle.net/U8Fcb/。然而:这在 Chrome(v31)和 FireFox(实际上有本地支持)中有效。但在 IE9 或 IE10 中无效(一个本地示例在 IE8 中似乎奇迹般地工作)。 - smhg
正如我在另一条评论中提到的那样:当你的表单已经在页面加载时存在时,这可能有效。但对于动态生成的表单,这似乎不是一个“完整”的解决方案。 - smhg
1
我将我的解决方案添加到了你的jsbin上,并且在chrome上运行良好。所以看起来你现在可能必须进行提交了。http://jsfiddle.net/KzF6s/1/ - Daniel Moses
显示剩余2条评论

0

在其他答案的评论中玩弄了一会儿小提琴之后,我决定为那些可以等待浏览器正确处理此问题的人制作此列表。

因此,总结一下,这些浏览器版本支持使用JavaScript生成的表单上的自动完成值:

  • FireFox 25
  • Chrome 33(当前版本为31,即将推出)
  • Internet Explorer 11(参考

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接