Я пытаюсь запретить веб-браузеру автоматически заполнять и автоматически заполнять поля моих форм в моем проекте 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"
также должно работать на вас.Это может быть не то, что вы ожидаете, но единственный способ добиться этого — эмулировать ввод с помощью
div
свойства a иcontenteditable
.Теперь angular не распознает div как элементы, как это происходит с a
<input type="text" />
, обновляяngModel
каждую введенную букву, поэтому мне пришлось создать директиву, чтобы она обновляла модель всякий раз, когда пользователь вводит div.Прошу прощения, что пример в angularjs 1.*, так как я не знаю angular2 , но у вас будет представление, как это сделать:
По сути, что он делает, так это то, что для каждого нажатия на div обновляется модель, назначенная div.
Теперь
form
не распознает атрибутname
в div, чтобы отправить его на сервер. Для этого вам просто нужно создать вход [скрытый] и присвоить ему значение модели, как в примере. Я оставлю это просто как пример, если это необходимо.Браузеры еще не договорились о том, что использовать, и вы можете видеть проблемы, которые это вызывает у нас. В моем случае у меня сработал атрибут autocomplete="off" поставив его в форму в chrome v60.0.3112.90 и Edge v40.15063.0.0, но возможно не у всех есть обновленный браузер и не все используют chrome или edge .
Это не самое элегантное решение, но оно отлично работает. Так что никаких отрицательных моментов.
То, что вы пытаетесь сделать, отключить автозаполнение, противоречит предпосылкам, продвигаемым такими компаниями, как Google, в которых указанная прерогатива принадлежит пользователю.
Если вы настаиваете на своем намерении, первым делом попробуйте то, что рекомендует Mozilla Developer Network.
autocomplete="off"
илиautocomplete="nope"
Вышеупомянутое может не работать в таких браузерах, как Chrome, потому что, как упоминалось ранее для Google, прерогатива автозаполнения принадлежит пользователю, а не разработчику. В этом случае помните, что автозаполнение полагается на подсказки, чтобы иметь возможность сопоставлять данные, хранящиеся в браузере, с данными формы, такими как
label
полейname
иid
По возможности используйте уникальные метки и имена.
Вместо пароля или пароля попробуйте "пароль". Вместо электронной почты попробуйте с идентификатором
Еще одна вещь, которую можно попробовать, — продублировать поля, скрыв первые из них, поскольку обычно автозаполняется только первое вхождение.
С другой стороны, помимо функции автозаполнения форм современные браузеры имеют самостоятельную функцию сохранения логинов и паролей, что еще больше усложняет задачу разработчика по предотвращению автоматического заполнения этих данных.
О коде в stacksnippet
В ОП упоминается, что
autocomplete="off"
он не работает, но он не включен в код, а вместо этого включен атрибутappnoautocomplete=""
.использованная литература
Что ж, кажется, что
autocomplete
в прошлом он часто использовался в таких версиях, как IE11, Chrome 34 и Firefox 30 , поэтому использовать его вообще невозможно. Тем не менее, я нашел несколько старый пост, в котором вы пытаетесь решить аналогичный вопрос, есть несколько путей, и, возможно, один из них сработает для вас. как отключить автозаполнение в формахПРИМЕЧАНИЕ: использование
autocomplete="off"
ininput
не будет работать, если форма также включена .Атрибут автозаполнения HTML
Изучив тему, не найдя окончательного решения проблемы, которое является простым и в то же время соответствует уже созданному стандарту, я решил запрограммировать решение и поделиться им, поскольку в какой-то момент любой разработчик столкнется с этой проблемой. потому что в какой-то момент вам придется создать форму ВХОДА .
Это решение пытается поддерживать уже созданный стандарт, и
javascript
, заставляя веб-браузерыautocomplete
уважать его, это атрибут HTML .Хотя стандарт в этом отношении очень полный, пример, который я оставляю здесь, поддерживает только значение
autocomplete="off"
на уровне тега<form>
e<input>
.Вы также можете поместить
checkbox
withid="autocomplete"
, чтобы принудительно установитьautocomplete="on"
глобальную область действия для всех страниц, на которых вы используете этот код (строки, управляющие этой функцией, закомментированы в коде, поскольку S O не разрешает их).Без лишних слов, вот рабочий пример кода:
Одним из способов решения этой проблемы было бы обнаружить изменение этого ввода и выполнить функцию, в которой поле получает пустое значение при первом выполнении. пример:
Вы использовали атрибут
autocomplete
управления вводом , https://www.w3schools.com/tags/att_input_autocomplete.aspоставляю пример ссылки