长话短说,使用 Firefox + Greasemonkey 或 Chrome + Tampermonkey 会更轻松。
枚举后台选项卡需要使用Shell.Application
object .Windows()
方法。模棱两可的窗口对象似乎打破了DOMelement.parentNode
和类似的,所以每次你导航 DOM 时,你都必须重新建立完整的层次结构,从tabCollection.item(i).document
。用户名字段的名称是用户、用户名、登录名、登录 ID、电子邮件还是其他名称?您可以尝试使用正则表达式来预测它,但如果您计划扩展此脚本以登录其他站点,则可能会涉及一些试验和错误。
然而,不可能的部分是表单提交。表单提交是否调用回发以在发布之前设置隐藏的输入值?如果是这样,那么form.submit()
在提交之前可能不会触发必要的事件,从而导致身份验证失败。我测试的两个网站就是这种情况。
If you could fire the click()
event of the submit button, that might help. But is the submit button a button? An input type=button? An image? A stylized hyperlink? A div? OK, so maybe sending Enter in the password field would be better. I've been experimenting with initKeyboardEvent
and passwordField.dispatchEvent(evt)
for a couple of hours now, and it seems that here again, the ambiguous window
object resulting from Shell.Application
is preventing success.
这是我的almost-工作解决方案。它是批处理 + Jscript 的混合体。使用 .bat 扩展名保存它,然后用它做你想做的事。 *耸耸肩*也许form.submit()
适用于您正在使用的网站吗?
@if (@CodeSection == @Batch) @then
@echo off & setlocal
cscript /nologo /e:JScript "%~f0"
goto :EOf
@end // end Batch / begin JScript hybrid code
var navOpenInBackgroundTab = 4096,
site = [
"http://www.site1.com/",
"http://www.site2.com/"
],
IE = WSH.CreateObject("InternetExplorer.Application"),
oSH = WSH.CreateObject("Shell.Application"),
username = 'username',
password = 'password';
IE.Visible = true;
for (var i=0; i<site.length; i++) {
IE.Navigate(site[i], i ? 4096 : null);
}
var tabs = oSH.Windows();
for (var x = 0; x < tabs.Count; x++) {
if (!!(tabs.item(x))) {
WSH.Echo('tab ' + x);
var entered = { 'username': 0, 'password': 0 };
while (tabs.item(x).Busy || tabs.item(x).ReadyState != 4) WSH.Sleep(50);
// sleep 1 second regardless, just in case there's some jquery crap going on
WSH.Sleep(1000);
for (var i in tabs.item(x).document.forms) {
if (i == 'length') break;
var inputs = tabs.item(x).document.forms[i].getElementsByTagName('input');
for (var j = inputs.length; j--;) {
if (/\b(login|user(name|id)?|e\-?mail)\b/i.test(inputs[j].name)
&& inputs[j].type.toLowerCase() == "text") {
entered.username = inputs[j];
inputs[j].value = username;
} else if (inputs[j].type.toLowerCase() == 'password') {
entered.password = inputs[j];
inputs[j].value = password;
}
}
if (entered.username && entered.password) {
tabs.item(x).document.forms[i].submit();
/* === NOT QUITE WORKING ===
try {
var evt = tabs.item(x).document.createEvent('KeyboardEvent');
// What is "window"? tabs.item(x) doesn't work, nor does IE.
evt.initKeyboardEvent('keypress', true, true, tabs.item(x),
false, false, false, false, 13, 13);
entered.password.dispatchEvent(evt);
}
catch(e) { WSH.Echo(e.message) }
*/
i = tabs.item(x).document.forms.length;
}
}
}
}
var IE = null;
另一个想法是做passwordElement.focus()
并使用WshShell.SendKeys()
发送 Enter,但随后您将无法在后台加载选项卡。我还没有找到以编程方式激活选项卡的方法;但如果它们在前台加载,则它们已经处于活动状态。虽然这不会在后台加载选项卡,但它比第一种方法效果更好。
@if (@CodeSection == @Batch) @then
@echo off & setlocal
cscript /nologo /e:JScript "%~f0"
goto :EOf
@end // end Batch / begin JScript hybrid code
var sites = {
"http://www.site1.com/" : {
'username': 'site1user',
'password': 'site1pass'
},
"http://www.site2.net/" : {
'username': 'site2user',
'password': 'site2pass'
}
},
IE = WSH.CreateObject("InternetExplorer.Application"),
oSH = WSH.CreateObject("Shell.Application"),
WshShell = WSH.CreateObject("WScript.Shell"),
proc = GetObject("winmgmts:").ExecQuery("SELECT Handle FROM Win32_Process "
+ "WHERE Name='iexplore.exe'"),
handle = new Enumerator(proc).item().Handle;
awesomeness:
for (var url in sites) {
// if not a new window, open a new tab
IE.Navigate(url, IE.Visible ? 2048 : null);
IE.Visible = true;
// give the tab a chance to load
WSH.Sleep(1000);
var tabs = oSH.Windows(),
tab = tabs.item(tabs.Count - 1),
entered = { 'username': 0, 'password': 0 };
while (tab.Busy || tab.ReadyState != 4) WSH.Sleep(50);
for (var i in tab.document.forms) {
if (i == 'length') break;
var inputs = tab.document.forms[i].getElementsByTagName('input');
for (var j = inputs.length; j--;) {
if (/\b(login|user(name|id)?|e\-?mail)\b/i.test(inputs[j].name)
&& inputs[j].type.toLowerCase() == "text") {
entered.username = inputs[j].value = sites[url].username;
} else if (inputs[j].type.toLowerCase() == 'password') {
entered.password = inputs[j];
inputs[j].value = sites[url].password;
}
if (entered.username && entered.password) {
// force IE window to have focus
while (!(WshShell.AppActivate(handle))) WSH.Sleep(50);
entered.password.focus();
WshShell.SendKeys('{END}{ENTER}');
continue awesomeness;
}
}
}
}
var IE = null;