经过大量的挖掘,我找到了答案。那么,不是一个答案,但为什么会发生这种情况。我希望这能节省一些时间。
当前基于WebKit的浏览器(截至2010年3月16日),例如, Safari和Chrome展示以下错误。也许有人可以看看。谢谢。问题1:如果页面A有多个表单元素F1和F2,并且第一个(按HTML形式出现)窗体F1的自动完成设置为“关闭”(即),但是F2具有自动完成设置到“开”(默认行为),然后导航离开页面A,然后点击浏览器后退按钮返回页面A,F1和F2可能会自动完成不正确。特别是,如果F1和F2都有具有相同名称和类型的输入元素,比如N和T(即),那么当使用后退按钮导航回页面A时,F1.N的值将自动与F2.N的值完成。问题2:首先,浏览器点击页面A,服务器返回一个带有表单元素F1和F2的HTML页面(这两个表单都设置了自动完成功能)。然后,用户导航离开页面A,然后使用浏览器后退按钮返回到页面A.在第二次访问页面A时,WebKit向服务器发出另一个A请求(这与FireFox的行为不同,后退按钮不向服务器发出添加请求)。如果服务器返回不同的HTML页面(例如,因为用户会话已注销),表单元素F3和F4与F1和F2不同,但是由具有相同名称和类型的输入元素组成,则F3和F4将自动填充F1和F2输入元素值,甚至为输入元素类型隐藏并提交。
解决
错误1:除非你有这个设置为相同的HTML网页上的所有形式永远不会使用自动完成=“关闭”。
错误2:特定的情况下,没有很好的通用解决方案。我们找到了一个可以接受的解决方法,通过包含隐藏表单来确保页面A的两个版本具有相似的表单;第一个版本有F1,F2,F3,第二个版本有F1,F2'和F3,其中F2'是F2的隐藏版本。如果我们不包含F2',那么页面A的第二个版本是F1,即使对于F3中的隐藏和提交元素,F3和F3也将自动填充F2的元素值。 WebKit的CODE
的
分析这两个错误发生在代码的同一部分,但也许可以被视为两个独立的错误。代码位于WebKit代码树的WebCore子目录中。
错误1:在Document :: formElementsState中,具有自动完成开启(通过HTMLInputElement :: saveFormControlState检查)的输入元素,将其状态保存在向量中。但是,在HTMLFormControlElementWithState :: finishParsingChildren中,无论自动完成是ON还是OFF,每个表单元素都会从上述向量中恢复状态。这导致错误1.
Bug的修复1:这应该是一个相当直接的修复 - finishParsingChildren不能恢复状态,如果元素具有自动完成关闭。
免责声明:我没有在Mac上发展。我只用它,我们开发一个网站。我今天浏览WebKit代码。因此,我没有创建或测试一个补丁。
的Bug 2.这要复杂得多。
我认为在一个设计决策无关的自动完成功能,WebKit是旨在重新抓取页面A如果用户正在使用后退按钮回到历史页面A.
(我有兴趣在听到这个也是如此)
基本上,WebKit做出了不正确的假设,即页面A的第二次获取导致与第一次获取相同的HTML或至少相同的一组表单。如果情况并非如此,那么自动完成逻辑不再产生正确/预期的行为。
当WebKit为页面保存状态时,它调用Document :: formElementsState,它只是创建一个对映射图,并将每个输入元素的名称,类型和值对放入映射中。如果两个单独格式中的两个输入元素具有相同的名称和类型,则这两个值都将被保存。
举例来说,假设页A具有形式F1和F2,F1和具有名称a1和a2输入元件,与类型T1和T2时,分别用值v1和v2。 F2具有名称为a3和a2的输入元素,分别具有类型t1和t2以及值v3和v4。WebKit将此页的状态保存为(在JSON中)
{“a1,t1”:[v1],“a2,t2”:[v2,v4],“a3,t1”:[v3]}
如果用户使用浏览器后退按钮重新访问页面A,WebKit将尝试使用上述状态从服务器获取的新版本页面A上自动完成表单。如果新版本的页面A与最后一个版本具有完全相同的形式,那么一切正常。如果不是,那么WebKit会产生不正确的行为。例如,假设第二次访问页面A,服务器返回一个表单F3,并且F3具有名称为a4和a2的输入元素,类型为t1和t2,则F3的a2元素将填充为v2,从之前保存页。
(注:存储状态和恢复状态,如在代码中使用的实际的逻辑,略有不同,但概念是相同的)
此问题表现在网站上时用户会话可能过期,和会话过期后,点击页面A可能会产生稍微不同的HTML。例如。可能会给你一个“请登录”表格,或者可能会给你大致相同的内容,但是顶部的搜索用户数据表格会出现一个登录表单。在这些情况下,可见的文本输入元素,隐藏的输入元素和提交输入元素可能都会通过WebKit更改其值。
问题2修复:这很困难,因为当用户使用后退按钮时,WebKit会重新提取页面A.如果新版本的页面A与旧版本不同,WebKit无法轻松地将表单的状态从旧版本的页面与某种形式(如果它存在)在新版本上进行匹配。实际上,您无法要求所有表单都具有相同的DOM标识,即使您这样做了,仍然不完全正确,因为DOM标识必须在HTML页面内是唯一的,但不需要在单独的HTML文档中是唯一的。
我能想到的唯一修复方法是:当您从第一次访问页面A保存状态时,采用页面的MD5或SHA1哈希,并将其保存为输入元素状态。当您回到页面A时,如果MD5或SHA1哈希值相同,则只能恢复状态。
很好的尝试,但没有奏效。 如果您仔细考虑,自动填充功能的确适用于浏览器功能,它可以完成您以前的答案。我看到的错误是Webkit尝试在用户点击“返回”按钮时在上一页“保留”用户输入数据的结果。 – OverClocked 2010-03-04 04:19:47
@ a1ex07:对不起,你的建议几乎是正确的。您必须关闭自动填充功能,而我之前对有关自动填充的评论与自动填写相似的说法不正确。不是。但诀窍是您必须关闭所有字段中的自动填充功能。看到我对自己的问题的“答案”。 – OverClocked 2010-03-16 21:09:52
我在清除某些隐藏输入的值时遇到了问题,并向表单添加了autocomplete ='off'来解决此问题。谢谢! – 2014-10-20 12:45:47