我遇到了chrome自动填充行为的几个形式的问题。
表单中的字段都有非常常见和准确的名称,例如“email”、“name”或“password”,并且它们还设置了autocomplete=“off”。
自动完成标志已经成功禁用了自动完成行为,当你开始输入时,会出现一个下拉的值,但没有改变Chrome自动填充字段的值。
这种行为是可以的,除了chrome填充输入不正确,例如填充电话输入与电子邮件地址。客户抱怨过这个问题,所以它被证实在很多情况下都发生了,而不是我在我的机器上本地操作的某种结果。
目前我能想到的唯一解决方案是动态生成自定义输入名称,然后在后端提取值,但这似乎是一种相当笨拙的解决这个问题的方法。是否有任何标签或怪癖,改变自动填充行为,可以用来解决这个问题?
Boom,谷歌Chrome和其他人尝试击败这然后。
我能够得到这个实现今天2017年9月7日,但使用在我的MVC视图中生成的随机字符串的FormCollection。
我会首先在我的登录页面的索引控制器中获得一个新的随机密钥,加密并创建一个新的完全唯一的随机字符串(我实际上使用了一个256位的cypher来执行此操作,以及一个唯一的cypher和认证密钥),然后在每个字符串的末尾附加纯文本“用户名”和“密码”,以帮助我从响应视图控制器识别用户名和密码。你也可以把这个普通字符串改成任何东西,只要你知道它的模式并且它是唯一的。
在我看来,我然后适当地使用这些变量,然后在响应控制器中—通过FormCollection搜索并找到匹配的变量—然后使用该项的Key-Value作为相应的用户名和密码进行适当的处理。
The other issue i had which i think is sneaky of Chrome, is that any
Any thoughts ?
<style>
@@font-face {
font-family: 'password';
font-style: normal;
font-weight: 400;
src: url(https://jsbin-user-assets.s3.amazonaws.com/rafaelcastrocouto/password.ttf);
}
</style>
<input type="text" name="@Model.UsernameRandomNameString" />
<input style="font-family: 'password'" type="text" name="@Model.PasswordRandomNameString" />
LogOnModel model = new LogOnModel()
{
UsernameRandomNameString = Cryptography.SimpleEncrypt("Username", UniqueGeneratorKey, UniqueGeneratorKey) + "Username",
PasswordRandomNameString = Cryptography.SimpleEncrypt("Password", UniqueGeneratorKey, UniqueGeneratorKey) + "Password",
};
I think it a hell of a workaround, but hey it works, and i think it could also be future proof unless google determines the URL of the page has key words in it, then appropriately just adds its stupid extensions on top on any input field - but that's a little drastic.
我的解决方案取决于三件事:
keydown事件
屏蔽字段名
在提交时删除字段值
首先,我们需要防止用户名和密码都自动补全,因此,最初我们将设置两个标志,i ->用户名和j ->密码为真值,因此如果没有任何keydown字段,i和j都将为真。
在可能的情况下,字段屏蔽发生在服务器端,通过传递随机字符串,它也可以很容易地使用客户端。
这是代码:
$(document).ready(function(){
i= true; //username flag
j= true; // password flag
$("#username{{$rand}}").keydown(function(e){
// {{$rand}} is server side value passed in blade view
// keyboard buttons are clicked in the field
i = false;
});
$("#passowrd{{$rand}}").keydown(function(e){
// {{$rand}} is server side value passed in blade view
// keyboard buttons are clicked in the field
j = false;
});
// Now we will use change event,
$("#username{{$rand}}").change(function(){
if($(this).val() != ''){ //the field has value
if(i){ // there is no keyboard buttons clicked over it
$(this).val(''); // blank the field value
}
}
})
$("#password{{$rand}}").change(function(){
if($(this).val() != ''){ // the same as username but using flag j
if(j){
$(this).val('');
}
}
})
$("#sForm").submit(function(e){ // the id of my form
$("#password-s").val($("#password{{$rand}}").val());
$("#username-s").val($("#username{{$rand}}").val());
// Here the server will deal with fields names `password` and `username` of the hidden fields
$("#username{{$rand}}").val('');
$("#password{{$rand}}").val('');
})
})
下面是HTML:
<form class="form-horizontal" autocomplete="off" role="form" id="sForm" method="POST" action="https://example.com/login">
<input type="hidden" name="password" id="password-s">
<input type="hidden" name="username" id="username-s">
<label for="usernameTDU3m4d3I5" class="col-md-3 control-label" style="white-space: nowrap">Username</label>
<input id="usernameTDU3m4d3I5" placeholder="Username" autocomplete="off" style="border-bottom-left-radius: 10px; border-top-right-radius: 10px; font-family: fixed; font-size: x-large;" type="text" class="form-control" name="usernameTDU3m4d3I5" value="" required="required" autofocus="">
<label for="passwordTDU3m4d3I5" class="col-md-3 control-label" style="white-space: nowrap">Password</label>
<input id="passwordTDU3m4d3I5" placeholder="Password" autocomplete="off" type="password" class="form-control" name="pa-TDU3m4d3I5" required="">
<button type="submit" class="btn btn-success">
<i class="fox-login" style="text-shadow: 0px 1px 0px #000"></i><strong>Login</strong>
</button>
</form>
上述解决方案确实不会消除或阻止用户名和密码的自动补全,但它使自动补全无用。也就是说,在没有敲击键盘按钮的情况下,字段值在提交之前将是空白的,因此用户将被要求输入它们。
更新
我们也可以,使用点击事件来防止自动完成用户列表出现在字段下面,如下所示:
$("#username{{$rand}}").click(function(){
$(this).val('');
i = true;
})
$("#password{{$rand}}").click(function(){
$(this).val('');
j = true;
})
限制:
这种解决方案可能无法在触摸屏设备中正常工作。
最后的更新
我已经完成了如下干净的实现:
preventAutoComplete = true; // modifier to allow or disallow autocomplete
trackInputs = {password:"0", username:"0"}; //Password and username fields ids as object's property, and "0" as its their values
// Prevent autocomplete
if(preventAutoComplete){
$("input").change(function(e){ // Change event is fired as autocomplete occurred at the input field
trackId = $(this).attr('id'); //get the input field id to access the trackInputs object
if (trackInputs[trackId] == '0' || trackInputs[trackId] != $(this).val()){ //trackInputs property value not changed or the prperty value ever it it is not equals the input field value
$(this).val(''); // empty the field
}
});
$("input").keyup(function(e){
trackId = $(this).attr('id');
trackInputs[trackId] = $(this).val(); //Update trackInputs property with the value of the field with each keyup.
});
}