html - 为什么 Chrome 会认为我的表单是信用卡表单?
问题描述
最小复制示例(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 都认为这是一张信用卡表格,并决定帮助我的用户输入他们的信用卡数据,这根本没有帮助(因为这不是信用卡表格)并且混淆了我的用户见鬼了:
我知道以下解决方法:
混淆第一个标签:
<label>Basisnum<span style="display:none">x</span>mer</label>
这行得通,但我需要做很多工作才能在我们的应用程序中实现这一点(标签不是硬编码的,因为它们可以本地化)。
autocomplete="cc-csc"
有效(即禁用自动完成),但它在语义上完全错误(它不是 CC-CSC 字段!),所以我宁愿避免这种情况,以防止在浏览器决定做一些“有用”的事情时进一步麻烦cc-csc 字段。例如,将其设置为 cc-csc 可以使移动浏览器显示一个仅限数字的键盘(这是有道理的,因为 csc 始终是数字的),我绝对不希望这样。
无论如何,我宁愿使用浏览器而不是反对它,因此我的问题是:
为什么会这样?(既然它同时出现在 Chrome 和“新”Edge 中,那一定是 Chromium 的问题,而且由于 Chromium 是开源的,我们应该能够看到这里发生了什么,对吧?)
额外问题:我如何(正式)告诉 Chromium 这不是信用卡表格?
笔记:
autocomplete="nope"
(或autocomplete="...some random data..."
)没有区别。- 这只是一个最小的示例——整个页面包含名称、类、ID 等等。
- 我很感谢人们在评论中提出解决方法。但是,我更愿意了解它发生的原因,而不是尝试随机的解决方法(如果可能的话,当然......)。
解决方案
这是因为 Chome 对德语信用卡表格的自动检测过于激进。特别是,您的表格包含
- 三个或更多领域,
- 其中一个被标记为 a
...nummer
,并且 - 另一个被标记为
...name
.
这是一个更简单的最小示例,它与当前的金丝雀版本的 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>
查看 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"
,但这在语义上是完全倒退的(错误地将字段标记为某种类型的信用卡字段以防止信用卡字段自动检测)。
我已经为此提交了一个错误报告,希望它有所帮助:
推荐阅读
- ruby - 从保留重音字符的字符串中删除非字母数字字符
- r - R Shiny CRUD 应用程序上的单选按钮问题
- python-3.x - Pandas 发送包含数据框的电子邮件作为可视化表格
- blockchain - Web3js 与没有元掩码的本地松露进行交互
- google-maps - 折线谷歌地图android中两条路径之间的航路点?
- javascript - service-worker.js中未添加的.html页面被缓存,可以离线使用?
- javascript - JSON 休息服务转 HTML 表格格式
- axon - 如何在微服务系统中使用 axon 和 Spring Cloud
- javascript - 基于先前值自动添加值的 JavaScript 循环
- matlab - 将代码文件保存到 .mat 文件