2016-01-11 15 views
17

Recentemente ho riscontrato un problema relativo alla funzionalità di completamento automatico del browser. Si potrebbe trovare nei moduli su pagine web.In che modo i browser memorizzano i dati per il completamento automatico e dove?

Il problema riguarda i dati, che vengono inseriti in altri campi a seconda della selezione del completamento automatico per un campo. Più in dettaglio è collegato all'uso di AngularJS.

Ho trovato argomenti riguardanti soluzioni alternative per l'angolare, ma ciò che mi interessa è dove vengono conservati i dati memorizzati dal browser e qual è la logica dietro la raccolta, quei dati.

  • C'è qualche elenco definito di campi, che viene visualizzato dal browser?
  • L'host dati (posizione) è specifico sul campo specifico?
  • Quando viene memorizzato dal browser? Sul modulo normale inviare eventi o altri eventi pure?

Grazie in anticipo.

+0

Is questo articolo è utile? [Compila automaticamente le tue informazioni nei moduli su Chrome] (https://support.google.com/chrome/answer/142893?p=settings_autofill&rd=1) – cuixiping

risposta

12

L'implementazione delle funzionalità di riempimento automatico dipende dal fornitore del browser. Se implementano il "Living HTML Standard" del gruppo di lavoro Web Hypertext Application Technology, paragrafo 4.10.19.8.1 (Controlli del modulo di compilazione automatica: l'attributo di completamento automatico) si applica.Lì, il seguente autofill field names sono definiti:

  • "nome"
  • "titolo onorifico-prefix"
  • "data-name"
  • "supplementare-name"
  • "-cognome"
  • "titolo onorifico-suffisso"
  • "nickname"
  • "username"
  • "new-password"
  • "corrente-password"
  • "organizzazione-title"
  • "organizzazione"
  • "street-address"
  • "indirizzo-line1"
  • "indirizzo -line2"
  • "indirizzo-Line3"
  • "indirizzo-level4"
  • "indirizzo-level3"
  • "indirizzo-Level2"
  • "indirizzo-level1"
  • "paese"
  • "-nome del paese"
  • "postal-code"
  • "cc-name"
  • "cc -given-nome-addizionale-name cc"
  • ""
  • "nome-cc-famiglia"
  • "cc-numero"
  • "cc-exp"
  • "cc-exp-mese"
  • "cc-exp-anno"
  • "cc-csc"
  • "cc-tipo"
  • "operazione-valuta "
  • "operazione-somma"
  • "linguaggio"
  • "compleanno"
  • "bday-day"
  • " bday mesi"
  • "bday anni"
  • "sesso"
  • "url"
  • "photo"

Consideriamo cromo, un rendendo popolare browser open source uso di questo standard .

In src/components/autofill/core/browser/form_structure.cc un sotto insieme di suddetti nomi dei campi di riempimento automatico vengono utilizzati per mappare questi internamente:

// Returns the Chrome Autofill-supported field type corresponding to the given 
// |autocomplete_attribute_value|, if there is one, in the context of the given 
// |field|. Chrome Autofill supports a subset of the field types listed at 
// http://is.gd/whatwg_autocomplete 
HtmlFieldType FieldTypeFromAutocompleteAttributeValue(
    const std::string& autocomplete_attribute_value, 
    const AutofillField& field) { 
    if (autocomplete_attribute_value == "name") 
    return HTML_TYPE_NAME; 

    if (autocomplete_attribute_value == "given-name") 
    return HTML_TYPE_GIVEN_NAME; 

    if (autocomplete_attribute_value == "additional-name") { 
    if (field.max_length == 1) 
     return HTML_TYPE_ADDITIONAL_NAME_INITIAL; 
    else 
     return HTML_TYPE_ADDITIONAL_NAME; 
    } 

    if (autocomplete_attribute_value == "family-name") 
    return HTML_TYPE_FAMILY_NAME; 

    if (autocomplete_attribute_value == "organization") 
    return HTML_TYPE_ORGANIZATION; 

    if (autocomplete_attribute_value == "street-address") 
    return HTML_TYPE_STREET_ADDRESS; 

    if (autocomplete_attribute_value == "address-line1") 
    return HTML_TYPE_ADDRESS_LINE1; 

    if (autocomplete_attribute_value == "address-line2") 
    return HTML_TYPE_ADDRESS_LINE2; 

    if (autocomplete_attribute_value == "address-line3") 
    return HTML_TYPE_ADDRESS_LINE3; 

    // TODO(estade): remove support for "locality" and "region". 
    if (autocomplete_attribute_value == "locality") 
    return HTML_TYPE_ADDRESS_LEVEL2; 

    if (autocomplete_attribute_value == "region") 
    return HTML_TYPE_ADDRESS_LEVEL1; 

    if (autocomplete_attribute_value == "address-level1") 
    return HTML_TYPE_ADDRESS_LEVEL1; 

    if (autocomplete_attribute_value == "address-level2") 
    return HTML_TYPE_ADDRESS_LEVEL2; 

    if (autocomplete_attribute_value == "address-level3") 
    return HTML_TYPE_ADDRESS_LEVEL3; 

    if (autocomplete_attribute_value == "country") 
    return HTML_TYPE_COUNTRY_CODE; 

    if (autocomplete_attribute_value == "country-name") 
    return HTML_TYPE_COUNTRY_NAME; 

    if (autocomplete_attribute_value == "postal-code") 
    return HTML_TYPE_POSTAL_CODE; 

    // content_switches.h isn't accessible from here, hence we have 
    // to copy the string literal. This should be removed soon anyway. 
    if (autocomplete_attribute_value == "address" && 
     base::CommandLine::ForCurrentProcess()->HasSwitch(
      "enable-experimental-web-platform-features")) { 
    return HTML_TYPE_FULL_ADDRESS; 
    } 

    if (autocomplete_attribute_value == "cc-name") 
    return HTML_TYPE_CREDIT_CARD_NAME; 

    if (autocomplete_attribute_value == "cc-number") 
    return HTML_TYPE_CREDIT_CARD_NUMBER; 

    if (autocomplete_attribute_value == "cc-exp") { 
    if (field.max_length == 5) 
     return HTML_TYPE_CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR; 
    else if (field.max_length == 7) 
     return HTML_TYPE_CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR; 
    else 
     return HTML_TYPE_CREDIT_CARD_EXP; 
    } 

    if (autocomplete_attribute_value == "cc-exp-month") 
    return HTML_TYPE_CREDIT_CARD_EXP_MONTH; 

    if (autocomplete_attribute_value == "cc-exp-year") { 
    if (field.max_length == 2) 
     return HTML_TYPE_CREDIT_CARD_EXP_2_DIGIT_YEAR; 
    else if (field.max_length == 4) 
     return HTML_TYPE_CREDIT_CARD_EXP_4_DIGIT_YEAR; 
    else 
     return HTML_TYPE_CREDIT_CARD_EXP_YEAR; 
    } 

    if (autocomplete_attribute_value == "cc-csc") 
    return HTML_TYPE_CREDIT_CARD_VERIFICATION_CODE; 

    if (autocomplete_attribute_value == "cc-type") 
    return HTML_TYPE_CREDIT_CARD_TYPE; 

    if (autocomplete_attribute_value == "transaction-amount") 
    return HTML_TYPE_TRANSACTION_AMOUNT; 

    if (autocomplete_attribute_value == "transaction-currency") 
    return HTML_TYPE_TRANSACTION_CURRENCY; 

    if (autocomplete_attribute_value == "tel") 
    return HTML_TYPE_TEL; 

    if (autocomplete_attribute_value == "tel-country-code") 
    return HTML_TYPE_TEL_COUNTRY_CODE; 

    if (autocomplete_attribute_value == "tel-national") 
    return HTML_TYPE_TEL_NATIONAL; 

    if (autocomplete_attribute_value == "tel-area-code") 
    return HTML_TYPE_TEL_AREA_CODE; 

    if (autocomplete_attribute_value == "tel-local") 
    return HTML_TYPE_TEL_LOCAL; 

    if (autocomplete_attribute_value == "tel-local-prefix") 
    return HTML_TYPE_TEL_LOCAL_PREFIX; 

    if (autocomplete_attribute_value == "tel-local-suffix") 
    return HTML_TYPE_TEL_LOCAL_SUFFIX; 

    if (autocomplete_attribute_value == "email") 
    return HTML_TYPE_EMAIL; 

    return HTML_TYPE_UNKNOWN; 
} 

Questo metodo viene utilizzato per aiutare durante l'analisi dei campi del modulo:

void FormStructure::ParseFieldTypesFromAutocompleteAttributes() { 
    const std::string kDefaultSection = "-default"; 

    has_author_specified_types_ = false; 
    has_author_specified_sections_ = false; 
    for (AutofillField* field : fields_) { 
    // To prevent potential section name collisions, add a default suffix for 
    // other fields. Without this, 'autocomplete' attribute values 
    // "section--shipping street-address" and "shipping street-address" would be 
    // parsed identically, given the section handling code below. We do this 
    // before any validation so that fields with invalid attributes still end up 
    // in the default section. These default section names will be overridden 
    // by subsequent heuristic parsing steps if there are no author-specified 
    // section names. 
    field->set_section(kDefaultSection); 

    // Canonicalize the attribute value by trimming whitespace, collapsing 
    // non-space characters (e.g. tab) to spaces, and converting to lowercase. 
    std::string autocomplete_attribute = 
     base::CollapseWhitespaceASCII(field->autocomplete_attribute, false); 
    autocomplete_attribute = base::ToLowerASCII(autocomplete_attribute); 

    // The autocomplete attribute is overloaded: it can specify either a field 
    // type hint or whether autocomplete should be enabled at all. Ignore the 
    // latter type of attribute value. 
    if (autocomplete_attribute.empty() || 
     autocomplete_attribute == "on" || 
     autocomplete_attribute == "off") { 
     continue; 
    } 

    // Any other value, even it is invalid, is considered to be a type hint. 
    // This allows a website's author to specify an attribute like 
    // autocomplete="other" on a field to disable all Autofill heuristics for 
    // the form. 
    has_author_specified_types_ = true; 

    // Tokenize the attribute value. Per the spec, the tokens are parsed in 
    // reverse order. 
    std::vector<std::string> tokens = base::SplitString(
     autocomplete_attribute, " ", base::KEEP_WHITESPACE, 
     base::SPLIT_WANT_NONEMPTY); 

    // The final token must be the field type. 
    // If it is not one of the known types, abort. 
    DCHECK(!tokens.empty()); 
    std::string field_type_token = tokens.back(); 
    tokens.pop_back(); 
    HtmlFieldType field_type = 
     FieldTypeFromAutocompleteAttributeValue(field_type_token, *field); 
    if (field_type == HTML_TYPE_UNKNOWN) 
     continue; 

    // The preceding token, if any, may be a type hint. 
    if (!tokens.empty() && IsContactTypeHint(tokens.back())) { 
     // If it is, it must match the field type; otherwise, abort. 
     // Note that an invalid token invalidates the entire attribute value, even 
     // if the other tokens are valid. 
     if (!ContactTypeHintMatchesFieldType(tokens.back(), field_type)) 
     continue; 

     // Chrome Autofill ignores these type hints. 
     tokens.pop_back(); 
    } 

    // The preceding token, if any, may be a fixed string that is either 
    // "shipping" or "billing". Chrome Autofill treats these as implicit 
    // section name suffixes. 
    DCHECK_EQ(kDefaultSection, field->section()); 
    std::string section = field->section(); 
    HtmlFieldMode mode = HTML_MODE_NONE; 
    if (!tokens.empty()) { 
     if (tokens.back() == kShippingMode) 
     mode = HTML_MODE_SHIPPING; 
     else if (tokens.back() == kBillingMode) 
     mode = HTML_MODE_BILLING; 
    } 

    if (mode != HTML_MODE_NONE) { 
     section = "-" + tokens.back(); 
     tokens.pop_back(); 
    } 

    // The preceding token, if any, may be a named section. 
    const std::string kSectionPrefix = "section-"; 
    if (!tokens.empty() && 
     base::StartsWith(tokens.back(), kSectionPrefix, 
         base::CompareCase::SENSITIVE)) { 
     // Prepend this section name to the suffix set in the preceding block. 
     section = tokens.back().substr(kSectionPrefix.size()) + section; 
     tokens.pop_back(); 
    } 

    // No other tokens are allowed. If there are any remaining, abort. 
    if (!tokens.empty()) 
     continue; 

    if (section != kDefaultSection) { 
     has_author_specified_sections_ = true; 
     field->set_section(section); 
    } 

    // No errors encountered while parsing! 
    // Update the |field|'s type based on what was parsed from the attribute. 
    field->SetHtmlType(field_type, mode); 
    } 

    was_parsed_for_autocomplete_attributes_ = true; 
} 
+0

Nel mio caso, la funzione di riempimento automatico di Chrome è consigliata per campi come "zip", "email", "telefono" in un unico modulo. Non ho trovato nomi di campi simili nella lista sopra. È un altro caso di riempimento automatico? – Eugene

+1

AFAIK questi nomi di campo non fanno parte di alcuno standard e pertanto sono soggetti alle decisioni di implementazione prese dal venditore. La risposta è per tutti i browser un po 'ampia. Se sei interessato a come Chromium lo fa, dai un'occhiata alle fonti collegate. '' 'src/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.h''' è anche abbastanza interessante in questo senso. –

-2

Nella mia esperienza, il completamento automatico di solito è specifico del campo e effettua una chiamata ajax quando eseguono il key-up dopo l'immissione del terzo carattere.

if (input.length === 3) 
    //call server on keyup 

Quindi memorizza il risultato. Successivamente, puoi semplicemente filtrare quel risultato sul lato client. Se ritornano indietro e immettono un nuovo inizio di 3 caratteri, interroga nuovamente e lo memorizza localmente. Spero che questo risponda alla tua domanda.

+0

Sei sicuro che stai parlando di moduli browser [completamento automatico] (http: //www.w3.org/TR/html5/forms.html#attr-form-autocomplete) funzionalità? – Eugene

+0

Ignora la mia risposta .. Ho pensato che stavi parlando di campi di completamento automatico dinamici personalizzati, ad esempio quando aggiungi uno dei tuoi contatti in una casella di testo interrogando il tuo database e offrendo opzioni di completamento. – gegillam

Problemi correlati