为什么 Chrome 认为我的表单是信用卡表单? [英] Why does Chrome think that my form is a credit card form?

查看:28
本文介绍了为什么 Chrome 认为我的表单是信用卡表单?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最小重现示例(


我知道以下解决方法:

  • 混淆第一个标签:

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

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


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

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

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


注意事项:

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

解决方案

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

  • 三个或更多字段,
  • 其中一个标记为 ...nummer,和
  • 另一个标记为 ...name.

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

<头><title>测试</title><身体><div><label>数字</label><输入类型=文本"/><输入类型=文本"/><br><label>名称</label><输入类型=文本"/>

</html>


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

const char kCardNumberRe[] =(add)?(?:card|cc|acct).?(?:number|#|no|num|field)";|(?

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

一旦找到信用卡号字段,就会出现一个标记为...name"的后续字段.被视为信用卡名称字段 (credit_card_field.cc):

//有时持卡人字段只是标记为姓名".很遗憾//这是一个危险的通用词来搜索,因为它经常会//匹配信用卡之前或之后的姓名(不是持卡人姓名)字段//字段.所以我们搜索name"只有当我们已经解析//至少还有一个信用卡字段,但尚未解析//到期日期(通常出现在最后).如果(字段 > 0 && !credit_card_field->expiration_month_ &&ParseField(扫描仪,base::UTF8ToUTF16(kNameOnCardContextualRe),&credit_card_field->持卡人_,{log_manager, kNameOnCardContextualRe"})) {继续;


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

我已经为此提交了错误报告,希望对您有所帮助:

Minimal repro example (jsfiddle, you need a credit card saved in your browser to see this issue):

<!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>

Both Chrome 85.0.4183.121 and Edge 85.0.564.63 think that this is a credit card form and decide to helpfully allow my users to enter their credit card data, which is not at all helpful (since this is not a credit card form) and confuses the heck out of my users:


I am aware of the following workarounds:

  • 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.


In any case, I'd rather work with the browser than against it, hence my question:

Why does this happen? (Since it occurs in both Chrome and "new" Edge, it must be some Chromium issue, and since Chromium is open-source, we should be able to see what happens here, right?)

Bonus question: How can I (officially) tell Chromium that this is not a credit card form?


Notes:

  • autocomplete="nope" (or autocomplete="...some random data...") doesn't make a difference.
  • This is just a minimal example - the full page has names, classes, ids and whatnot.
  • I am grateful for people suggesting workarounds in the comments. I would, however, prefer to understand why it happens rather than trying random workarounds (if that is possible, of course...).

解决方案

It's because Chome's auto-detection of German-language credit card forms is too aggressive. In particular, your form contains

  • three or more fields,
  • one of which is labeled as a ...nummer, and
  • another one is labeled as a ...name.

Here is an even simpler minimal example that reproduces the same issue with the current canary version of Chrome (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>


Looking at the source of Chromium, we can see that the following regex is used to detect credit card number fields (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))";

We can see that (almost) every field labeled with "...nummer" (= German for "number") is considered a credit card number field!

Once a credit card number field is found, a subsequent field labeled "...name" is treated as a credit card name field (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;


Unfortunately, there is no "official" way to tell Chrome that "this is really not a credit card field". The most common workaround is autocomplete="cc-csc", but this is semantically completely backwards (mis-labeling a field as a certain type of credit card field to prevent credit card field auto-detection).

I have submitted a bug report for this, let's hope it helps:

这篇关于为什么 Chrome 认为我的表单是信用卡表单?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆