2010-03-03 13 views
6

Il seguente problema si verifica sia su Safari che su Chrome, quindi probabilmente un problema con WebKit.Il pulsante Indietro di Safari e Chrome cambia nascosto e invia valori nei moduli

Pagina A: una pagina che richiede di effettuare il login a vedere, contiene una forma che ha un tipo = pulsante di invio, con name = presentare, e value = un

Pagina B: qualche altra pagina

Pagina C: chiedi all'utente di accedere alla pagina, contiene un modulo con un tipo = invia pulsante, con nome = invia e valore = c

Pagina visite utente A, quindi pagina B. Quindi inattività e viene interrotta la sessione di accesso dell'utente . Il pulsante utente torna indietro per tornare alla pagina A. Il browser reindirizza l'utente alla pagina C.

Su Safari e Chrome, quando viene eseguito il rendering di C, il modulo nella pagina C ha il pulsante type = submit, name = submit, ma value si presenta come "a".

Se si ricarica mentre sulla pagina C, "c" appare come valore del nome = pulsante di invio.

Lo stesso problema si verifica con tipo = campi di input nascosti; quando l'utente preme il tasto indietro, i loro valori vengono anche cambiati in qualche altro valore da qualche altra forma. Inoltre, questo problema si presenta anche senza il reindirizzamento, con solo invio e ritorno. In questo caso la pagina precedente esegue il rendering con valori errati per le variabili CGI nascoste e inviate.

Finora l'unica correzione che riesco a ottenere è utilizzare Javascript per reimpostare type = hidden e type = invia valori di variabile, dopo il caricamento della pagina C, per assicurarsi che i valori siano corretti. Ma non è pulito e universalmente applicabile.

A corto di WebKit che risolve questo errore, qualcuno ha eseguito una soluzione migliore?

Grazie.

risposta

17

Dopo aver scavato molto, ho trovato la risposta a questo. Beh, non una risposta, ma perché questo accade. Spero che questo salvi altre persone un po 'di tempo.

Browser basati su WebKit correnti (al 3/16/2010), ad es. Safari e Chrome presentano i seguenti bug. Forse qualcuno può dare un'occhiata. Grazie.

Bug 1: Se una pagina A ha più elementi di forma F1 e F2, e il primo modulo (in ordine di aspetto in HTML), F1, ha il completamento automatico impostato su "off" (cioè), ma F2 ha il completamento automatico impostato su "on" (comportamento predefinito), quindi dopo aver navigato lontano dalla pagina A, e quindi premendo il pulsante Indietro del browser per tornare alla pagina A, F1 e F2 potrebbero essere completati automaticamente in modo errato. In particolare, se F1 e F2 hanno entrambi elementi di input con lo stesso nome e tipo, ad esempio N e T (cioè), quindi quando si ritorna alla pagina A utilizzando il pulsante Indietro, il valore di F1.N verrà completato automaticamente con il valore F2.N .

Bug 2: In primo luogo, il browser colpisce la pagina A e il server restituisce una pagina HTML con gli elementi del modulo F1 e F2 (entrambi i moduli hanno l'opzione di completamento automatico attivata). Quindi, l'utente si allontana dalla pagina A e successivamente torna alla pagina A utilizzando il pulsante Indietro del browser. Alla seconda visita della pagina A, WebKit invia un'altra richiesta di A al server (questo differisce dal comportamento di FireFox, dove sul pulsante Indietro non viene inviata alcuna richiesta di aggiunta al server). Se il server restituisce una pagina HTML diversa (ad es.poiché la sessione utente è stata disconnessa), con gli elementi F3 e F4 diversi da F1 e F2, ma costituiti da elementi di input con lo stesso nome e tipo, F3 e F4 verranno completati automaticamente con i valori degli elementi di input F1 e F2, anche per tipo di elemento di input nascosto e invia.

aggirare

Bug 1: non utilizzare mai autocomplete = "off" a meno che non si dispone di questo set per tutti i moduli sulla stessa pagina HTML.

Bug 2: caso specifico, nessuna soluzione generica buona. Abbiamo trovato un lavoro accettabile includendo moduli nascosti per assicurarci che due versioni della pagina A abbiano forme simili; la prima versione ha F1, F2, F3 e la seconda ha F1, F2 'e F3, dove F2' è una versione nascosta di F2. Se non includiamo F2 ', la seconda versione della pagina A è F1, e F3 e F3 saranno completati automaticamente con i valori degli elementi di F2, anche per gli elementi nascosti e di invio in F3.

ANALISI del codice WebKit

Questi due errori si verificano nella stessa parte del codice, ma probabilmente può essere considerato come due insetti separati. Il codice si trova nella sottodirectory WebCore dell'albero dei codici WebKit.

Bug 1: in Document :: formElementsState, gli elementi di input con completamento automatico attivato (controllato tramite HTMLInputElement :: saveFormControlState), hanno i loro stati salvati in un vettore. Tuttavia, in HTMLFormControlElementWithState :: finishParsingChildren, ogni elemento del modulo, indipendentemente dal completamento automatico è ON o OFF, ripristina lo stato dal vettore sopra menzionato. Questo risulta nel bug 1.

Bug 1 Correzione: questa dovrebbe essere una correzione abbastanza semplice - finishParsingChildren non dovrebbe ripristinare lo stato se l'elemento ha il completamento automatico disattivato.

Disclaimer: Non sviluppo su Mac. Lo uso solo e sviluppiamo un sito web. Oggi sfoglio il codice WebKit. Quindi, non ho creato o testato una patch.

Bug 2. Questo è molto più complesso.

suppongo che in una decisione di progettazione estranei a completamento automatico, WebKit è stato progettato per ri-fetch pagina A se l'utente sta usando il pulsante Indietro per tornare indietro nella storia alla pagina A.

(sarei interessato nell'udire anche questo)

Fondamentalmente, WebKit fa presupporre erroneamente che il secondo recupero della pagina A abbia come risultato lo stesso codice HTML, o almeno lo stesso insieme di moduli, come il primo recupero. Se questo non è il caso, la logica di autocompletamento non produce più il comportamento corretto/previsto.

Quando WebKit salva lo stato per una pagina, chiama Document :: formElementsState, che crea semplicemente una mappa di coppie e inserisce nella mappa il nome di ciascun elemento di input + tipo e coppia di valori. Se due elementi di input in due moduli separati hanno lo stesso nome e tipo, entrambi i valori vengono salvati.

Ad esempio, la pagina A ha forme F1 e F2 e F1 ha elementi di input con i nomi a1 e a2, con tipi t1 e t2, rispettivamente con valori v1 e v2. F2 ha elementi di input con i nomi a3 e a2, con tipi t1 e t2, e valori v3 e v4, rispettivamente.WebKit salva lo stato di questa pagina come (in notazione JSON)

{"a1, t1": [v1], "a2, t2": [v2, v4], "a3, t1": [v3]}

Se l'utente rivisita la pagina A utilizzando il pulsante Indietro del browser, WebKit tenterà di completare automaticamente i moduli sulla nuova versione della pagina A, recuperati dal server, utilizzando lo stato precedente. Se la nuova versione della pagina A ha esattamente le stesse forme dell'ultima, allora tutto funziona. In caso contrario, WebKit produce un comportamento errato. Ad esempio, supponiamo che la seconda pagina temporale venga recuperata, che il server restituisca solo una forma F3 e che F3 abbia elementi di input con i nomi a4 e a2, con i tipi t1 e t2, quindi l'elemento a2 di F3 verrà popolato con v2, salvato dal precedente pagina.

(Nota: effettivo logica di memorizzazione dello stato e stato recupero, come usato nel codice, sono leggermente diverse, ma l'idea è la stessa)

Questo problema si manifesta in siti web quando sessioni utente può scadere, e dopo che una sessione scade, il colpire la pagina A può produrre un HTML leggermente diverso. Per esempio. può darti un modulo di "login", o ti può fornire più o meno lo stesso contenuto, ma al posto di un modulo di dati utente di ricerca in alto, viene visualizzato un modulo di accesso. In questi casi, l'elemento di immissione del testo visibile, l'elemento di input nascosto e gli elementi di input di invio possono tutti avere i loro valori modificati da WebKit.

Bug 2 Correzione: questo è difficile, perché WebKit recupera pagina A quando l'utente utilizza il pulsante Indietro. Se la nuova versione della pagina A è diversa dalla vecchia versione, WebKit non può facilmente corrispondere allo stato di una form dalla vecchia versione della pagina ad una forma, se esiste, sulla nuova versione. Non è possibile richiedere realisticamente che tutti i moduli abbiano lo stesso ID DOM e, anche se lo si fa, non è ancora del tutto corretto poiché gli ID DOM devono essere univoci all'interno di una pagina HTML, ma non devono essere univoci tra documenti HTML separati.

L'unica soluzione mi viene in mente è questa: quando si salva lo stato dalla prima volta che si visita la pagina A, prende un MD5 o SHA1 hash della pagina, e memorizzare che con lo stato elemento di input. Quando torni alla pagina A, ripristina lo stato solo se l'hash MD5 o SHA1 è lo stesso.

4

Non sono sicuro, ma provare ad aggiungere il completamento automatico = 'off' a tutti i moduli.

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

Buona prova, ma non ha funzionato. Se ci pensi, il completamento automatico è proprio per la funzione browser che completa i moduli con le tue risposte precedenti. Il bug che sto vedendo è il risultato di Webkit che tenta di "conservare" i dati inseriti dall'utente in una pagina precedente, quando l'utente preme il pulsante "Indietro". – OverClocked

+0

@ a1ex07: scusa, il tuo suggerimento è quasi corretto. Devi disattivare il completamento automatico e il mio commento precedente sul completamento automatico è simile al riempimento automatico non è corretto. Non è. Ma il trucco è che devi disattivare il completamento automatico in TUTTI i campi. Vedi la mia "risposta" alla mia domanda. – OverClocked

+0

Ho riscontrato un problema con Chrome che cancella il valore di alcuni input nascosti e l'aggiunta del completamento automatico = 'off' al modulo risolto. Grazie! –

1

autocomplete="off"

non funziona per me. Ho trovato un'altra soluzione, è possibile utilizzare text campi, nascondere questi campi usando

DIV style="display:none"

e aggiungere input_type="text" value="s" campi nel tag DIV

+0

Il 'display: none' ha funzionato per me in Google Chrome. Il valore del modulo A, ad es. 'order_type =" new "' è stato inserito in modo errato nel modulo B. Qualcuno che ha inviato il modulo di aggiornamento B avrebbe avuto 'order_type =" new "' anche se l'html effettivo (view source) ha detto 'order_type =" up "'. Ora sto ottenendo risultati wacko da Mobile Safari (Mozilla/5.0 (iPad; CPU OS 7_0_4 come Mac OS X) AppleWebKit/537.51.1 (KHTML, come Gecko) Versione/7.0 Mobile/11B554a Safari/9537.53) In questo caso dovrebbe avere "order_id =" new "' o 'order_id =" 1 "'. Quando tornano, riempie automaticamente il loro * nome * nel campo order_id! –

Problemi correlati