2010-03-03 6 views
6

Le problème suivant se produit à la fois sur Safari et Chrome, donc probablement un problème WebKit.Safari et Chrome bouton de modification des modifications cachées et soumettre des valeurs dans les formulaires

Page A: une page qui vous oblige à vous connecter pour voir, contient une forme qui a un type = bouton Soumettre, avec le nom = soumettre, et la valeur = a

Page B: une autre page

Page C: demande à l'utilisateur de se connecter, contient un formulaire avec un bouton type = submit, avec name = submit et value = c

Visites d'utilisateur page A, puis page B. Puis, les inactifs et la session de connexion de l'utilisateur expirent . L'utilisateur retourne le bouton pour revenir à la page A. Le navigateur redirige l'utilisateur vers la page C.

Sur Safari et Chrome, lorsque C est affiché, le formulaire de la page C comporte le bouton type = submit, name = submit, mais value apparaît comme "a".

Si vous rechargez à la page C, "c" apparaît comme la valeur du bouton name = submit.

Le même problème apparaît avec type = champs d'entrée masqués; Lorsque l'utilisateur appuie sur le bouton Précédent, ses valeurs sont également remplacées par une autre valeur provenant d'un autre formulaire. En outre, ce problème apparaît également sans la redirection, avec juste soumettre puis de retour. Dans ce cas, la page précédente affiche des valeurs incorrectes pour les variables CGI masquées et soumises. Jusqu'à présent, la seule solution que je peux trouver est d'utiliser Javascript pour réinitialiser le type = hidden et type = soumettre les valeurs de variables, après chargement de la page C, pour s'assurer que les valeurs sont correctes. Mais ce n'est pas propre et universellement applicable.

En attendant que WebKit corrige cette erreur, quelqu'un a-t-il trouvé une meilleure solution?

Merci.

Répondre

17

Après beaucoup de fouilles, j'ai trouvé la réponse à cette question. Eh bien, pas une réponse, mais pourquoi cela arrive. J'espère que cela permettra aux autres de gagner du temps.

Navigateurs WebKit actuels (au 16/03/2010), par ex. Safari et Chrome, présentent les bugs suivants. Peut-être que quelqu'un peut jeter un coup d'oeil. Merci. Bogue 1: Si une page A a plusieurs éléments de formulaire F1 et F2, et que le premier formulaire (dans l'ordre d'apparition en HTML) est F1, la saisie semi-automatique est désactivée (c'est-à-dire), mais F2 a la saisie semi-automatique à "on" (comportement par défaut), puis après avoir quitté la page A, puis appuyé sur le bouton de retour du navigateur pour retourner à la page A, F1 et F2 peut être complétée automatiquement de façon incorrecte. En particulier, si F1 et F2 ont tous deux des éléments d'entrée avec le même nom et le même type, par exemple N et T (ie), la valeur de F1.N sera automatiquement complétée avec la valeur de F2.N lors de la navigation vers la page A . Bug 2: Premièrement, le navigateur rencontre la page A, et le serveur renvoie une page HTML avec les éléments de formulaire F1 et F2 (les deux formulaires ont la saisie semi-automatique activée). Ensuite, l'utilisateur quitte la page A et revient à la page A en utilisant le bouton de retour du navigateur. Lors des deuxièmes visites de la page A, WebKit envoie une autre demande de A au serveur (ce qui diffère du comportement de FireFox, où aucune demande d'ajout n'est envoyée au serveur sur le bouton de retour). Si le serveur renvoie une page HTML différente (par ex.parce que la session utilisateur est déconnectée), avec les éléments de formulaire F3 et F4 différents de F1 et F2, mais composés d'éléments d'entrée de même nom et type, alors F3 et F4 seront complétés automatiquement avec les valeurs d'entrée F1 et F2, même pour le type d'élément d'entrée caché et soumettre.

AUTOUR DE TRAVAIL

Bug 1: ne jamais utiliser autocomplete = "off" à moins que vous avez cet ensemble pour TOUS les formulaires sur la même page HTML. Bogue 2: spécifique au cas, pas de bonne solution générique.

Nous avons trouvé un travail acceptable en incluant des formulaires cachés pour nous assurer que deux versions de la page A ont des formes similaires; la première version a F1, F2, F3, et la deuxième a F1, F2 ', et F3, où F2' est une version cachée de F2. Si nous n'incluons pas F2 ', alors la deuxième version de la page A est F1, et F3 et F3 seront complétées automatiquement avec les valeurs des éléments de F2, même pour les éléments cachés et soumis dans F3.

ANALYSE de WebKit CODE

Ces deux bugs se produisent dans la même partie du code, mais peut probablement être considéré comme deux bogues séparés. Le code se trouve dans le sous-répertoire WebCore de l'arborescence de code WebKit. Bogue 1: dans Document :: formElementsState, les éléments d'entrée dont la saisie semi-automatique est activée (vérifiée via HTMLInputElement :: saveFormControlState) ont leurs états sauvegardés dans un vecteur. Cependant, dans HTMLFormControlElementWithState :: finishParsingChildren, chaque élément de formulaire, que la saisie semi-automatique soit activée ou non, restaure l'état à partir du vecteur susmentionné. Cela entraîne le bogue 1.

Bogue 1 Correction: ce devrait être une solution assez simple - finishParsingChildren ne devrait pas restaurer l'état si l'autocomplétion de l'élément est désactivée. Clause de non responsabilité: Je ne développe pas sur Mac.

Je l'utilise seulement et nous développons un site web. Je viens de parcourir le code WebKit aujourd'hui. Par conséquent, je n'ai pas créé ou testé un patch.

Bug 2. Ceci est beaucoup plus complexe.

Je suppose que, dans une décision de conception sans rapport avec saisie semi-automatique, WebKit est conçu pour récupérer à la page A si l'utilisateur utilise le bouton retour pour revenir dans l'histoire à la page A.

(Je serais intéressé En entendant cela aussi)

Fondamentalement, WebKit fait l'hypothèse incorrecte que la deuxième extraction de la page A aboutit au même HTML, ou au moins au même ensemble de formulaires, que le premier fetch. Si ce n'est pas le cas, la logique de saisie semi-automatique ne produit plus le comportement correct/attendu. Lorsque WebKit enregistre un état pour une page, il appelle Document :: formElementsState, qui crée simplement une carte de paires et place la paire nom + valeur et type de chaque élément d'entrée dans la carte. Si deux éléments d'entrée dans deux formulaires distincts ont le même nom et le même type, les deux valeurs sont enregistrées. Par exemple, disons que la page A a les formes F1 et F2, et F1 a les éléments d'entrée avec les noms a1 et a2, avec les types t1 et t2, avec les valeurs v1 et v2 respectivement. F2 a des éléments d'entrée avec les noms a3 et a2, avec les types t1 et t2, et les valeurs v3 et v4, respectivement.WebKit enregistre l'état de cette page sous (en notation JSON)

{"a1, t1": [v1], "a2, t2": [v2, v4], "a3, t1": [v3]} Si l'utilisateur revient sur la page A en utilisant le bouton de retour du navigateur, WebKit essaiera de remplir automatiquement les formulaires de la nouvelle version de la page A, récupérés du serveur, en utilisant l'état ci-dessus. Si la nouvelle version de la page A a exactement les mêmes formes que la dernière, alors tout fonctionne. Si ce n'est pas le cas, WebKit génère un comportement incorrect. Par exemple, supposons que la deuxième page A est récupérée, le serveur renvoie une seule forme F3, et F3 a des éléments d'entrée avec les noms a4 et a2, avec les types t1 et t2, alors l'élément a2 de F3 sera rempli avec v2. page.

(Note: la logique réelle de stockage de l'état et la récupération de l'état, tel qu'il est utilisé dans le code, sont légèrement différentes, mais l'idée est la même)

Ce problème se manifeste sur des sites Web lorsque des sessions utilisateur peut prendre fin, et après l'expiration d'une session, en tapant sur la page A, vous pouvez produire un HTML légèrement différent. Par exemple. peut vous donner un formulaire "s'il vous plaît connecter", ou peut vous donner à peu près le même contenu, mais à la place d'un formulaire de recherche de données de l'utilisateur sur le dessus, un formulaire de connexion apparaît. Dans ces cas, l'élément d'entrée de texte visible, l'élément d'entrée caché et les éléments d'entrée de soumission peuvent tous avoir leurs valeurs modifiées par WebKit.

Bug 2 Fix: Ceci est difficile, car WebKit récupère la page A lorsque l'utilisateur utilise le bouton de retour. Si la nouvelle version de la page A est différente de l'ancienne version, WebKit ne peut pas facilement faire correspondre l'état d'un formulaire de l'ancienne version de la page à une forme quelconque, si elle existe déjà, sur la nouvelle version. Vous ne pouvez pas exiger que tous les formulaires aient le même identifiant DOM, et même si c'est le cas, ce n'est pas tout à fait correct puisque les identifiants DOM doivent être uniques dans une page HTML, mais ne doivent pas nécessairement être uniques. La seule difficulté que je peux penser est la suivante: lorsque vous sauvegardez l'état de la première fois que vous visitez la page A, prenez un hachage MD5 ou SHA1 de la page et stockez-le avec l'état de l'élément d'entrée. Lorsque vous revenez à la page A, ne restaurez l'état que si le hachage MD5 ou SHA1 est le même.

4

Je ne suis pas sûr, mais essayez d'ajouter autocomplete = 'off' à tous les formulaires.

<form .... autocomplete = 'off'> 
+0

Bien essayé, mais n'a pas fonctionné. Si vous y pensez, la saisie semi-automatique est vraiment pour la fonctionnalité du navigateur qui complète vos formulaires avec vos réponses précédentes. Le bug que je vois, est un résultat de Webkit essayer de "préserver" les données entrées par l'utilisateur sur une page précédente, lorsque l'utilisateur clique sur le bouton "Retour". – OverClocked

+0

@ a1ex07: désolé, votre suggestion est presque juste. Vous devez désactiver la saisie semi-automatique, et mon commentaire précédent sur le fait que la saisie semi-automatique est similaire au remplissage automatique est incorrect. Ce n'est pas. Mais l'astuce est que vous devez désactiver la saisie semi-automatique dans TOUS les champs. Voir ma "réponse" à ma propre question. – OverClocked

+0

J'ai rencontré un problème avec la suppression par Chrome de la valeur de certaines entrées masquées et l'ajout d'autocomplete = 'off' au formulaire l'a résolu. Merci! –

1

autocomplete="off"

ne fonctionne pas pour moi. J'ai trouvé une autre solution, peut utiliser text champs, masquer ces champs à l'aide

DIV style="display:none"

et ajouter input_type="text" value="s" champs dans la balise DIV

+0

Le 'display: none' a fonctionné pour moi dans Google Chrome. La valeur du formulaire A, par ex. 'order_type =" new "' a été incorrectement mis en forme B. Quelqu'un soumettant la mise à jour Form B aurait 'order_type =" new "' même si le html réel (view source) dit 'order_type =" up "'. Maintenant, je reçois des résultats wacko de Mobile Safari (Mozilla/5.0 (iPad, CPU OS 7_0_4 comme Mac OS X) AppleWebKit/537.51.1 (KHTML, comme Gecko) Version/7.0 Mobile/11B554a Safari/9537.53) Dans ce cas, il devrait avoir 'order_id =" new "' ou 'order_id =" 1 "'. Quand ils reviennent, il remplit automatiquement leur * nom * dans le champ order_id! –