为什么 Chrome 认为我的表单是信用卡表单?

6

最小化的复现示例(jsfiddle,您需要在浏览器中保存一张信用卡才能看到此问题):

<!DOCTYPE html>
<html>
<head>
    <title>Test</title>
</head>
<body>
    <form method="post" action="Test.html" autocomplete="off">
        <div>
            <label>Basisnummer</label>
            <input type="text" />
            <input type="text" />
            <br>

            <label>Markenname</label>
            <input type="text" />
        </div>
    </form>
</body>
</html>

Chrome 85.0.4183.121和Edge 85.0.564.63都认为这是一个信用卡表单,并决定帮助我的用户输入他们的信用卡数据,这对我的用户来说一点也不有用(因为这不是一个信用卡表单),并且会让他们感到困惑:

screen shot


我了解以下解决方法:

  • Obfuscating the first label:

    <label>Basisnum<span style="display:none">x</span>mer</label>
    

    That works, but I'd be a lot of work to implement this in our application (the labels are not hard-coded since they can be localized).

  • autocomplete="cc-csc" works (i.e., disables auto-completion), but it's semantically completely wrong (it's not a CC-CSC field!), so I'd rather avoid that to prevent further trouble down the road when browsers decide to do something "helpful" to cc-csc fields. For example, setting it as cc-csc could make mobile browsers show a numeric-only keyboard (makes sense, since a csc is always numeric), and I definitely don't want that.


无论如何,我更愿意与浏览器一起工作,而不是反对它,因此我的问题是: 为什么会发生这种情况? (由于它在Chrome和“新”Edge中都出现了,所以这必须是某种Chromium问题,并且由于Chromium是开源的,我们应该能够看到这里发生了什么,对吧?)
奖励问题:我如何(正式地)告诉Chromium这不是信用卡表单?

注:

  • autocomplete="nope"(或autocomplete="...some random data...")没有区别。
  • 这只是一个最小化的示例 - 完整页面有名称、类、ID等。
  • 我感谢评论中建议解决方法的人。然而,我更愿意理解为什么会发生这种情况,而不是尝试随机的解决方法(如果可能的话......)。

有趣的事实:似乎将标签名称更改为英文会停止自动完成功能:https://jsfiddle.net/8gLxpwsj/ - Ava_Katushka
@Ava_Katushka:是的,我们也注意到了。只有在界面语言为德语时才会发生这种情况。 - Heinzi
这对我来说发生在一个只有一个名为fullName的输入框的应用程序中。本地环境是en-US。在应用程序中根本没有类似于数字或cc-字段的东西,但每次用户被提示输入他们的全名时,Chrome建议输入他们的信用卡号码。 - JHH
2个回答

5
这是因为Chrome自动检测德语信用卡表单的方式过于激进。特别是,您的表单包含:
  • 三个或更多字段,
  • 其中一个标记为...nummer
  • 另一个标记为...name
这里有一个更简单的最小示例,使用Chrome当前的canary版本(87.0.4278.0)也能重现同样的问题:
<!DOCTYPE html>
<html>
<head>
    <title>Test</title>
</head>
<body>
    <div>
        <label>Nummer</label>
        <input type="text" />
        <input type="text" />
        <br>

        <label>Name</label>
        <input type="text" />
    </div>
</body>
</html>

浏览 Chromium 的源码时,我们可以看到以下正则表达式用于检测信用卡号字段(components/autofill/core/common/autofill_regex_constants.cc):

const char kCardNumberRe[] =
    "(add)?(?:card|cc|acct).?(?:number|#|no|num|field)"
    "|(?<!telefon|haus|person|fødsels)nummer"  // de-DE, sv-SE, no
    "|カード番号"                              // ja-JP
    "|Номер.*карты"                            // ru
    "|信用卡号|信用卡号码"                     // zh-CN
    "|信用卡卡號"                              // zh-TW
    "|카드"                                    // ko-KR
    // es/pt/fr
    "|(numero|número|numéro)(?!.*(document|fono|phone|réservation))";

我们可以看到几乎所有标记为“...nummer”(德语中的“号码”)的字段都被视为信用卡号字段!
一旦找到信用卡号字段,随后标记为“...name”的字段将被视为信用卡名称字段(来源:credit_card_field.cc)。
// Sometimes the cardholder field is just labeled "name". Unfortunately
// this is a dangerously generic word to search for, since it will often
// match a name (not cardholder name) field before or after credit card
// fields. So we search for "name" only when we've already parsed at
// least one other credit card field and haven't yet parsed the
// expiration date (which usually appears at the end).
if (fields > 0 && !credit_card_field->expiration_month_ &&
    ParseField(scanner, base::UTF8ToUTF16(kNameOnCardContextualRe),
               &credit_card_field->cardholder_,
               {log_manager, "kNameOnCardContextualRe"})) {
  continue;

很遗憾,没有“正式”的方法告诉Chrome:“这不是一个信用卡字段”。 最常见的解决方法是 autocomplete="cc-csc" ,但这在语义上完全相反(误将字段标记为某种类型的信用卡字段以防止自动检测信用卡字段)。

我已经提交了一个错误报告,希望它有所帮助:


1

您可以明确设置自动完成值为HTML自动完成属性的最接近的近似值

我使用"tel"表示Basisnummer,使用"organization"表示Markenname:

<form method="post" action="Test.html" autocomplete="off">
    <div>
        <label>Basisnummer</label>
        <input type="text" autocomplete="tel"/>
        <input type="text" />
        <br>

        <label>Markenname</label>
        <input type="text" autocomplete="organization"/>
    </div>
</form>

它禁用了信用卡号自动填充。 JSfiddle


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接