我试图阻止 Web 浏览器在我的 Angular 项目中自动填充和自动完成表单的字段,因为它会加载我添加的样式。
在我的 HTML 中,我尝试将字段设置为只读,然后当它们通过 JS 事件获得焦点时删除只读,但这仅适用于避免初始自动填充,然后是自动完成帮助出现。
<section>
<form novalidate [formGroup]="formGroup" (ngSubmit)="onClickSignIn()">
<img src="assets/images/logo.png"/>
<md-input-container>
<input mdInput type="email" placeholder="Email" [formControl]="formGroup.controls['email']" #email appNoAutoComplete readonly>
</md-input-container>
<md-input-container>
<input mdInput type="password" placeholder="Contraseña" [formControl]="formGroup.controls['password']" #password>
</md-input-container>
<button md-button type="submit" [disabled]="formGroup.invalid">ENTRAR</button>
<div id="forgotten-password"><a (click)="onClickForgottenPassword()">¿Has olvidado la contraseña?</a></div>
</form>
</section>
防止初始自动填充的指令。
import { Directive, ElementRef, HostListener } from '@angular/core';
@Directive({
selector: '[appNoAutoComplete]',
})
export class NoAutoCompleteDirective {
constructor(private el: ElementRef) {}
@HostListener('focus', ['$event'])
public onFocus() {
if (this.el.nativeElement.hasAttribute('readonly')) {
this.el.nativeElement.removeAttribute('readonly');
this.el.nativeElement.blur();
this.el.nativeElement.focus();
}
}
}
我一直在阅读几种方法来解决我的问题,但我没有找到任何可以正常工作的方法,几乎所有方法都说要执行我的指令中描述的操作并放置 autocomplete="off" 属性
我在 Google Chrome 中进行测试。
更新
呈现的 HTML。
<app-signin _nghost-c0="" class=""><section _ngcontent-c0="">
<form _ngcontent-c0="" novalidate="" ng-reflect-form="[object Object]" class="ng-touched ng-dirty ng-valid">
<img _ngcontent-c0="" src="assets/images/logo.png">
<md-input-container _ngcontent-c0="" class="mat-input-container ng-tns-c1-0 ng-touched ng-dirty ng-valid"><div class="mat-input-wrapper"><div class="mat-input-flex"><!--bindings={
"ng-reflect-ng-if": "0"
}--><div class="mat-input-infix">
<input _ngcontent-c0="" appnoautocomplete="" class="mat-input-element ng-touched ng-dirty ng-valid" mdinput="" placeholder="Email" type="email" ng-reflect-form="[object Object]" ng-reflect-placeholder="Email" ng-reflect-type="email" id="md-input-1" aria-invalid="false">
<span class="mat-input-placeholder-wrapper"><!--bindings={
"ng-reflect-ng-if": "true"
}--><label class="mat-input-placeholder ng-tns-c1-0 mat-float" for="md-input-1">Email <!--bindings={
"ng-reflect-ng-if": "false"
}--></label></span></div><!--bindings={
"ng-reflect-ng-if": "0"
}--></div><div class="mat-input-underline"><span class="mat-input-ripple"></span></div><div class="mat-input-subscript-wrapper" ng-reflect-ng-switch="hint"><!--bindings={
"ng-reflect-ng-switch-case": "error"
}--><!--bindings={
"ng-reflect-ng-switch-case": "hint"
}--><div class="mat-input-hint-wrapper ng-tns-c1-0 ng-trigger ng-trigger-transitionMessages" style="opacity: 1; transform: translateY(0%);"><!--bindings={
"ng-reflect-ng-if": ""
}--><div class="mat-input-hint-spacer"></div></div></div></div></md-input-container>
<md-input-container _ngcontent-c0="" class="mat-input-container ng-tns-c1-1 ng-dirty ng-valid ng-touched"><div class="mat-input-wrapper"><div class="mat-input-flex"><!--bindings={
"ng-reflect-ng-if": "0"
}--><div class="mat-input-infix">
<input _ngcontent-c0="" class="mat-input-element ng-dirty ng-valid ng-touched" mdinput="" placeholder="Contraseña" type="password" ng-reflect-form="[object Object]" ng-reflect-placeholder="Contraseña" ng-reflect-type="password" id="md-input-3" aria-invalid="false">
<span class="mat-input-placeholder-wrapper"><!--bindings={
"ng-reflect-ng-if": "true"
}--><label class="mat-input-placeholder ng-tns-c1-1 mat-float" for="md-input-3">Contraseña <!--bindings={
"ng-reflect-ng-if": "false"
}--></label></span></div><!--bindings={
"ng-reflect-ng-if": "0"
}--></div><div class="mat-input-underline"><span class="mat-input-ripple"></span></div><div class="mat-input-subscript-wrapper" ng-reflect-ng-switch="hint"><!--bindings={
"ng-reflect-ng-switch-case": "error"
}--><!--bindings={
"ng-reflect-ng-switch-case": "hint"
}--><div class="mat-input-hint-wrapper ng-tns-c1-1 ng-trigger ng-trigger-transitionMessages" style="opacity: 1; transform: translateY(0%);"><!--bindings={
"ng-reflect-ng-if": ""
}--><div class="mat-input-hint-spacer"></div></div></div></div></md-input-container>
<button _ngcontent-c0="" class="mat-button" md-button="" type="submit" ng-reflect-disabled="false"><span class="mat-button-wrapper">ENTRAR</span><div class="mat-button-ripple mat-ripple" md-ripple="" ng-reflect-trigger="[object HTMLButtonElement]" ng-reflect-centered="false" ng-reflect-disabled="false"></div><div class="mat-button-focus-overlay"></div></button>
<div _ngcontent-c0="" id="forgotten-password"><a _ngcontent-c0="">¿Has olvidado la contraseña?</a></div>
</form>
</section></app-signin>
一行总结:
autocomplete="new-password"
您正在使用类型的字段
password
。无论您是否拥有该属性autocomplete="off"
,浏览器都会询问用户是否要保存密码。如果用户接受,浏览器将尝试自动完成它。此功能是从Firefox 38、Chrome 34和IE 11开始开发的,作为一种安全措施。
由于人们认为多亏了这一点,用户现在可以输入一个非常复杂的密码(或不输入)并且永远不会记住它,希望浏览器会自动完成他们的密码。
无论如何,人们认为要禁用此行为(即使在稍后保存密码后也自动填充),可以使用该属性
autocomplete="new-password"
。但是,
autocomplete="new-password"
一般不会实施。但无论如何,如果浏览器不理解分配的值,它也不会太努力。所以;autocomplete="cualquier-cosa"
也应该为你工作。这可能不是您所期望的,但我能够实现它的唯一方法是使用 a
div
和 property模拟输入contenteditable
。现在 angular 不会像使用 a
<input type="text" />
那样通过更新ngModel
每个键入的字母来将 div 识别为元素,因此我必须创建一个指令,以便每当用户在 div 中键入时它都会更新模型。我很抱歉该示例在angularjs 1.* 中,因为我不知道angular2,但您会有如何做到这一点的想法:
本质上,它所做的是对于 div 上的每个 keyup,它都会更新分配给 div 的模型。
现在
form
无法识别name
div 上的属性以将其发送到服务器。为此,您只需要创建一个 input[hidden] 并将模型的值分配给它,就像在示例中一样。如果有必要,我将把它作为一个例子。浏览器尚未就使用什么达成一致,您可以看到这给我们带来的问题。就我而言, autocomplete="off" 属性对我有用,方法是将其放入 chrome v60.0.3112.90 和 Edge v40.15063.0.0 的表单中,但可能不是每个人都有更新的浏览器,也不是每个人都使用 chrome 或 edge .
这不是最优雅的解决方案,但效果很好。所以没有负分。
您尝试做的事情是禁用自动完成功能,这违背了 Google 等公司提倡的前提,其中所述特权对应于用户。
如果你坚持用心,第一件事就是尝试 Mozilla 开发者网络推荐的东西
autocomplete="off"
或autocomplete="nope"
以上在 Chrome 等浏览器中可能会失败,因为正如前面提到的谷歌,自动完成的特权是用户的,而不是开发者的。在这种情况下,请记住,自动完成依赖于提示,以便能够将存储在浏览器中的数据与表单数据相匹配,例如
label
字段标签name
和id
如果可能,请使用唯一的标签和名称。
尝试使用“密码”代替密码或密码。而不是电子邮件尝试使用标识符
要尝试的另一件事是通过隐藏第一个字段来复制字段,因为通常只有第一次出现是自动完成的。
另一方面,现代浏览器除了表单自动补全功能外,还有独立的保存用户名和密码的功能,这让开发者更难防止这些数据被自动填写。
关于stacksnippet中的代码
OP提到
autocomplete="off"
它不起作用但它不包含在代码中,而是属性被包含appnoautocomplete=""
。参考
嗯,看来
autocomplete
以前在IE11、Chrome 34、Firefox 30等版本中使用的比较多,所以根本不可行。但是,我发现了一篇有些旧的帖子,您在其中尝试解决类似的问题,有多种途径可供选择,也许其中一种对您有用。如何禁用表单上的自动完成功能注意:如果表单也打开,
autocomplete="off"
使用ininput
将不起作用HTML 自动完成属性
在研究了该主题但没有找到问题的明确解决方案之后,这很简单,同时尊重已经创建的标准,我决定编写一个解决方案并分享它,因为在某些时候任何开发人员都会遇到这个问题因为在某些时候此时您将不得不创建一个LOGIN 表单。
该解决方案试图维护已经创建的标准,并通过
javascript
使WEB 浏览器autocomplete
尊重它,它是HTML属性虽然这方面的标准非常完善,但我这里留下的例子只支持标签e
autocomplete="off"
级别的值。<form>
<input>
您还可以放置一个
checkbox
withid="autocomplete"
以强制将autocomplete="on"
用作您使用此代码的所有页面的全局范围(控制此功能的行在代码中被注释掉,因为S O不允许它们)。事不宜迟,这是代码的工作示例:
解决这个问题的一种方法是检测这个输入的变化,并执行一个函数,在第一次执行时,该字段被赋予一个空值。例子:
autocomplete
您已经使用了输入控件属性, https://www.w3schools.com/tags/att_input_autocomplete.asp我留下链接的例子