公司的做账系统,用户在系统里设置保存了国税网的账号密码以后,下次点击进入国税网,能够直接进入国税系统。
之前的解决方案是pupptteer模拟登录一遍拿到cookie等登录凭证后,保存到数据库,然后插件请求接口拿到cookie,直接写入浏览器,但是国税网登录新版改版,单单设置cookie很多功能会失效。所以直接想使用插件实现自动登录,类似pupptteer模拟用户登录。
1.点击进入国税网,把用户信息放在登录网址后面带过去
2.在插件里截取用户信息,并判断是否需要执行自动登录
3.获取对应的输入框,将用户信息赋值进去,但这时候会发现,虽然输入框有值,点击登录还是会提示填写,这是因为新版页面是vue写的,单单赋值是不会绑定到对应的变量上的,需要在赋值完以后触发一下input事件
4.需要模拟用户滑动滑块,最后模拟点击登录按钮
btn = document.querySelector(".handler");
mousedown = document.createEvent("MouseEvents");
rect = btn.getBoundingClientRect();
x = rect.x || rect.left;
y = rect.y || rect.top;
w = document
.querySelector(".drag")
.getBoundingClientRect().width;
// 点击滑块
mousedown.initMouseEvent(
"mousedown",
true,
true,
window,
0,
x,
y,
x,
y,
false,
false,
false,
false,
0,
null
);
btn.dispatchEvent(mousedown);
dx = 0;
dy = 0;
// 滑动滑块
intervaltimer = setInterval(function () {
var mousemove = document.createEvent("MouseEvents");
var _x = x + dx + 200;
var _y = y + dy;
mousemove.initMouseEvent(
"mousemove",
true,
true,
window,
0,
_x,
_y,
_x,
_y,
false,
false,
false,
false,
0,
null
);
btn.dispatchEvent(mousemove);
if (_x - x >= w) {
clearInterval(intervaltimer);
var mouseup = document.createEvent("MouseEvents");
mouseup.initMouseEvent(
"mouseup",
true,
true,
window,
0,
_x,
_y,
_x,
_y,
false,
false,
false,
false,
0,
null
);
btn.dispatchEvent(mouseup);
setTimeout(function () {
$(".loginCls").click();
load.hide();
}, 300);
} else {
dx +=
parseInt(Math.random() * (300 - 200) + 200) / 23;
dy += parseInt(Math.random() * 10 - 3);
}
}, 30);
5.这个时候已经可以正常模拟登录了,但是当点击第二次时,出现新的问题
问题1:第二次换个账号进去的时候,上个账号的登录凭证还在,会直接进入上个账号的系统
解决方法:每次先清除对应的登录凭证
问题2:浏览器如果用户启用了记住密码功能,下次进入会默认填充一个,而且是直接覆盖在输入框上,导致代码无法直接操作输入框(如赋值点击等任何操作)
百度之后说给输入框加上autocomplete=“off”和autocomplete=“new-password”可以解决,但f12发现输入框已经有这两个属性。所有这个方法对国产浏览器无效,测试发现有这两个属性的话,谷歌浏览器的表现是会在输入框下面有保存过的密码可供选择,而不是直接覆盖,所以应该是国产浏览器直接无视了这些属性。
另一种说法是,给输入框加上readonly属性,这样便不会自动覆盖填充,然后用户focus的时候再取消readonly即可。但是现在页面是别人的,不像自己写的代码可以初始这样做。并不好实现。
思路:一进入页面便以极短的时间间隔循环去给输入框加上这个属性直到加上为止,在浏览器赋值之前看能不能加上。
测试结果:可行
至此,问题解决