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

Hei*_*nzi 6 html forms google-chrome input autofill

最小重现示例(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>
Run Code Online (Sandbox Code Playgroud)

Chrome 85.0.4183.121 和 Edge 85.0.564.63 都认为这是信用卡表单,并决定允许我的用户输入他们的信用卡数据,但这根本没有帮助(因为这不是信用卡表单)并且令人困惑我的用户真是太糟糕了:

截屏


我知道以下解决方法:

  • 混淆第一个标签:

    <label>Basisnum<span style="display:none">x</span>mer</label>
    
    Run Code Online (Sandbox Code Playgroud)

    这可行,但我需要做很多工作才能在我们的应用程序中实现这一点(标签不是硬编码的,因为它们可以本地化)。

  • autocomplete="cc-csc"有效(即禁用自动完成),但它在语义上完全错误(它不是 CC-CSC 字段!),所以我宁愿避免这种情况,以防止当浏览器决定做一些“有帮助”的事情时出现进一步的麻烦cc-csc 字段。例如,将其设置为 cc-csc 可以使移动浏览器显示仅数字键盘(这是有道理的,因为 csc 始终是数字),我绝对不希望这样。


无论如何,我宁愿使用浏览器而不是反对它,因此我的问题是:

为什么会出现这种情况?(既然它出现在 Chrome 和“新”Edge 中,那么一定是 Chromium 的问题,而且由于 Chromium 是开源的,我们应该能够看到这里发生了什么,对吧?)

额外问题:我如何(正式)告诉 Chromium 这不是信用卡表格?


笔记:

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

Hei*_*nzi 5

这是因为 Chome 对德语信用卡表格的自动检测过于激进。特别是,您的表格包含

\n
    \n
  • 三个或更多字段,
  • \n
  • 其中之一被标记为 a ...nummer,并且
  • \n
  • 另一个标记为...name.
  • \n
\n

这是一个更简单的最小示例,它重现了当前 Canary 版本的 Chrome (87.0.4278.0) 的相同问题:

\n
<!DOCTYPE html>\n<html>\n<head>\n    <title>Test</title>\n</head>\n<body>\n    <div>\n        <label>Nummer</label>\n        <input type="text" />\n        <input type="text" />\n        <br>\n\n        <label>Name</label>\n        <input type="text" />\n    </div>\n</body>\n</html>\n
Run Code Online (Sandbox Code Playgroud)\n
\n

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

\n
const char kCardNumberRe[] =\n    "(add)?(?:card|cc|acct).?(?:number|#|no|num|field)"\n    "|(?<!telefon|haus|person|f\xc3\xb8dsels)nummer"  // de-DE, sv-SE, no\n    "|\xe3\x82\xab\xe3\x83\xbc\xe3\x83\x89\xe7\x95\xaa\xe5\x8f\xb7"                              // ja-JP\n    "|\xd0\x9d\xd0\xbe\xd0\xbc\xd0\xb5\xd1\x80.*\xd0\xba\xd0\xb0\xd1\x80\xd1\x82\xd1\x8b"                            // ru\n    "|\xe4\xbf\xa1\xe7\x94\xa8\xe5\x8d\xa1\xe5\x8f\xb7|\xe4\xbf\xa1\xe7\x94\xa8\xe5\x8d\xa1\xe5\x8f\xb7\xe7\xa0\x81"                     // zh-CN\n    "|\xe4\xbf\xa1\xe7\x94\xa8\xe5\x8d\xa1\xe5\x8d\xa1\xe8\x99\x9f"                              // zh-TW\n    "|\xec\xb9\xb4\xeb\x93\x9c"                                    // ko-KR\n    // es/pt/fr\n    "|(numero|n\xc3\xbamero|num\xc3\xa9ro)(?!.*(document|fono|phone|r\xc3\xa9servation))";\n
Run Code Online (Sandbox Code Playgroud)\n

我们可以看到(几乎)每个标有“...nummer”(= 德语“数字”)的字段都被视为信用卡号字段!

\n

找到信用卡号字段后,标记为“...name”的后续字段将被视为信用卡名称字段 ( credit_card_field.cc ):

\n
// Sometimes the cardholder field is just labeled "name". Unfortunately\n// this is a dangerously generic word to search for, since it will often\n// match a name (not cardholder name) field before or after credit card\n// fields. So we search for "name" only when we\'ve already parsed at\n// least one other credit card field and haven\'t yet parsed the\n// expiration date (which usually appears at the end).\nif (fields > 0 && !credit_card_field->expiration_month_ &&\n    ParseField(scanner, base::UTF8ToUTF16(kNameOnCardContextualRe),\n               &credit_card_field->cardholder_,\n               {log_manager, "kNameOnCardContextualRe"})) {\n  continue;\n
Run Code Online (Sandbox Code Playgroud)\n
\n

不幸的是,没有“官方”方式告诉 Chrome“这实际上不是信用卡字段”。最常见的解决方法autocomplete="cc-csc",但这在语义上完全倒退(将字段错误标记为某种类型的信用卡字段以防止信用卡字段自动检测)。

\n

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

\n\n


Ava*_*hka 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>
Run Code Online (Sandbox Code Playgroud)

它确实禁用卡号自动完成。 JS小提琴