登录和重定向用户脚本失败,没有错误,也没有重定向?

Login and redirect userscript fails with no errors and no redirect?

正在尝试创建一个 Greasemonkey 脚本来自动填写一些表格,我希望脚本在提交表格后转到另一个 URL。

// ==UserScript==
// @name     usersaime
// @description fills data form for user and pass 
// @include https://tramites.saime.gob.ve/*
// @version  1.1
// @grant    none
// ==/UserScript==
document.getElementById('LoginForm_username').value = "user";
document.getElementById('LoginForm_password').value = "1234";

setTimeout(function() {
    document.getElementById('login_button').click();
}, 2000);

window.addEventListener('load', function(event) {
    // all resources finished loading
    window.location = 'https://tramites.saime.gob.ve/index/example/example';
});

window.location 根本不起作用。我还尝试了 window.location.hrefwindow.location.replace,以及 window.location 的 setTimeout 函数。没有任何效果。

控制台上没有错误。

尝试过:

登录 page/form 是 https://tramites.saime.gob.ve/index.php?r=site/login
成功登录后,它会转到 https://tramites.saime.gob.ve/index.php?r=tramite/tramite/——我想重定向它。

简单、直接的答案:
window.location 对您不起作用的原因是:

  1. window.location 调用是在 window load 事件处理程序中进行的。
  2. 目标页面就是其中之一,load 事件几乎在 DOMContentLoaded 事件之后立即触发。
  3. 默认情况下,用户脚本在 DOMContentLoaded 触发,但在这种情况下,加载事件在您的脚本运行时已经触发。

真实答案:
那个问题代码有很多问题:

  1. 它不会跟踪和说明进程的 状态。该脚本在许多(种类)页面上触发,并且必须根据状态表现不同。
  2. 页面 is/are 广泛 AJAX 驱动。代码没有正确说明这一点。
  3. 加载事件在这种情况下不是特别有用。
  4. 前面提到的脚本触发与负载竞争条件。
  5. 在这样的脚本中硬编码登录凭据意味着您会被攻击,这只是时间和损失程度的问题。

您需要跟踪和区分至少 3 个不同的状态,使用页面的 URL and/or 页面上的关键节点的组合 and/or 脚本 stores/passes 的状态变量].

以下用户脚本说明了该过程,尽管我无法在站点上对其进行测试,并且为简单起见省略了 the recommended authentication framework。 :

// ==UserScript==
// @name     _Login and then redirect an AJAX-driven page
// @include  https://tramites.saime.gob.ve/*
// @require  https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js
// @require  https://gist.github.com/raw/2625891/waitForKeyElements.js
// @grant    GM_addStyle
// @grant    GM.getValue
// ==/UserScript==
//- The @grant directives are needed to restore the proper sandbox.

//--- Different pages require different actions
if (location.search.includes ("site/login") ) {  // initial login page

    //-- Wait for page to initialize
    waitForKeyElements ("#login_button:visible", loginWhenReady);
}
else if (location.search.includes ("tramite/tramite") ) {  // successful login page
    //-- Just redirect
    location.assign ("https://tramites.saime.gob.ve/index/example/example");
}
else {
    //-- All other pages, no action needed.
}

function loginWhenReady (jNode) {
    //-- Demo purposes only!  Use framework or password manager instead!
    $("#LoginForm_username").val ("user");
    $("#LoginForm_password").val ("1234");

    clickNode (jNode);  //  Login button passed in by WFKE
}
function clickNode (jNode) {
    var clickEvent  = document.createEvent ('MouseEvents');
    clickEvent.initEvent ('click', true, true);
    jNode[0].dispatchEvent (clickEvent);
}


可能的快速简便的解决方案:

  1. 如果且仅当 (IIF) post 登录页面总是
    https://tramites.saime.gob.ve/index.php?r=tramite/tramite/.
  2. 并且 IIF 该页面未用于您关心的任何其他内容...

那么下面的用户脚本可能足以满足您的需要:

// ==UserScript==
// @name     _Quick and dirty post login redirect
// @include  https://tramites.saime.gob.ve/index.php?r=tramite/tramite*
// @grant    none
// @run-at   document-start
// ==/UserScript==

location.replace ("https://tramites.saime.gob.ve/index/example/example");