Safari和Chrome上都会出现以下问题,因此可能是WebKit问题.
页面A:要求您登录查看的页面,包含一个具有type = submit按钮的表单,其中name = submit,value = a
第B页:其他一些页面
页面C:询问用户登录页面,包含一个带有type = submit按钮的表单,其中name = submit和value = c
用户访问页面A,然后访问页面B.然后空闲和用户的登录会话超时.用户点击后退按钮返回到页面A.浏览器将用户重定向到页面C.
在Safari和Chrome上,当呈现C时,页面C上的表单具有type = submit按钮,name = submit,但值显示为"a".
如果在页面C上重新加载,"c"将显示为name = submit按钮的值.
type = hidden输入字段会出现同样的问题; 当用户点击后退按钮时,它们的值也会从其他某种形式更改为其他值.此外,此问题也显示没有重定向,只需提交然后返回.在这种情况下,前一页面呈现的隐藏和提交CGI变量的值不正确.
到目前为止,我能想到的唯一修复是在页面C加载后使用Javascript重置type = hidden和type = submit变量值,以确保值正确.但这并不干净,普遍适用.
没有WebKit修复此错误,有没有人遇到更好的解决方法?
谢谢.
经过多次挖掘,我找到了答案.好吧,不是答案,但为什么会这样.我希望这能节省一些时间.
当前基于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:从不使用autocomplete ="off",除非您在同一HTML页面上为所有表单设置了此设置.
错误2:具体案例,没有好的通用解决方案.我们找到了一个可接受的工作,包括隐藏的表单,以确保页面A的两个版本具有相似的形式; 第一个版本有F1,F2,F3,第二个版本有F1,F2'和F3,其中F2'是F2的隐藏版本.如果我们不包括F2',则页面A的第二个版本是F1,F3和F3将使用F2的元素值自动完成,即使对于F3中的隐藏和提交元素也是如此.
WebKit代码分析
这两个错误出现在代码的相同部分,但可能被视为两个独立的错误.代码位于WebKit代码树的WebCore子目录中.
错误1:在文献:: formElementsState中,具有自动完成输入元件接通(经由HTMLInputElement :: saveFormControlState选中),已经它们的状态保存在一个载体中.然而,在HTMLFormControlElementWithState :: finishParsingChildren,每形式元素,如果无论自动完成是ON还是OFF,从上述矢量恢复状态.这导致错误1.
错误1修复:这应该是一个相当直接的修复 - 如果元素已关闭自动完成,则finishParsingChildren不应恢复状态.
免责声明:我不在Mac上开发.我只使用它,我们开发了一个网站.我今天只是浏览WebKit代码.因此,我没有创建或测试过补丁.
错误2.这要复杂得多.
我假设在与自动完成无关的设计决策中,如果用户使用后退按钮返回历史记录到页面A,则WebKit旨在重新获取页面A.
(我也有兴趣听到这个)
从根本上说,WebKit做出了错误的假设,即第二次获取页面A会产生与第一次获取相同的HTML或至少相同的一组表单.如果不是这种情况,则自动完成逻辑不再产生正确/预期的行为.
当WebKit的一个页面保存状态时,它调用文献:: 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 ID,即使你做的,这仍然是不完全正确的,因为DOM IDS需要是一个HTML页面中是唯一的,但并不需要跨越不同的HTML文档独特.
我能想到的唯一的解决方法是这样的:当你从你访问网页A上的第一次保存的状态,采取了MD5或页面的SHA1哈希值,并存储与输入元素的状态.当您返回到页面A时,仅在MD5或SHA1哈希值相同时才恢复状态.