2010-12-10 13 views
6

Estoy usando Selenium para probar una aplicación web y no puedo modificar el código de JavaScript de la aplicación. Estoy tratando de rastrear el número de solicitudes pendientes de AJAX mediante el uso de GreaseMonkey para reemplazar XMLHttpRequest.send. El nuevo envío() básicamente ajustará lo que se estableció como la devolución de llamada de estado regular, verificará el estado de Ready, incrementará o disminuirá el contador según corresponda y llamará a la función de devolución de llamada original.Intentando hacer un seguimiento del número de solicitudes pendientes de AJAX en firefox

El problema que estoy teniendo que parece ser un tema privilegio porque si simplemente navegar a una página en un navegador normal de Firefox, Firebug abierta y pegar el siguiente código, que parece funcionar bien:

document.ajax_outstanding = 0; 
if (typeof XMLHttpRequest.prototype.oldsend != 'function') { 
    XMLHttpRequest.prototype.oldsend = XMLHttpRequest.prototype.send; 
    XMLHttpRequest.prototype.send = function() { 
     console.log('in new send'); 
     console.log('this.onreadystatechange = ' + this.onreadystatechange); 
     this.oldonreadystatechange = this.onreadystatechange; 
     this.onreadystatechange = function() { 
      if (this.readyState == 2) { 
       /* LOADED */ 
       document.ajax_outstanding++; 
       console.log('set ajax_outstanding to ' + document.ajax_outstanding); 
      } 
      this.oldonreadystatechange.handleEvent.apply(this, arguments); 
      if (this.readyState == 4) { 
       /* COMPLETED */ 
       document.ajax_outstanding--; 
       console.log('set ajax_outstanding to ' + document.ajax_outstanding); 
      } 
     }; 
     this.oldsend.apply(this, arguments); 
    }; 
} 

Ahora si uso una versión ligeramente modificada de ese fragmento en un script de usuario de Greasemonkey, así:

unsafeWindow.document.ajax_outstanding = 0; 
if (typeof unsafeWindow.XMLHttpRequest.prototype.oldsend != 'function') { 
    unsafeWindow.XMLHttpRequest.prototype.oldsend = unsafeWindow.XMLHttpRequest.prototype.send; 
    unsafeWindow.XMLHttpRequest.prototype.send = function() { 
     GM_log('in new send'); 
     GM_log('this.onreadystatechange = ' + this.onreadystatechange); 
     this.oldonreadystatechange = this.onreadystatechange; 
     this.onreadystatechange = function() { 
      if (this.readyState == 2) { 
       /* LOADED */ 
       unsafeWindow.document.ajax_outstanding++; 
       GM_log('set ajax_outstanding to ' + unsafeWindow.document.ajax_outstanding); 
      } 
      this.oldonreadystatechange.handleEvent.apply(this, arguments); 
      if (this.readyState == 4) { 
       /* COMPLETED */ 
       unsafeWindow.document.ajax_outstanding--; 
       GM_log('set ajax_outstanding to ' + unsafeWindow.document.ajax_outstanding); 
      } 
     }; 
     this.oldsend.apply(this, arguments); 
    }; 
} 

y voy a una página, hacer algo que causa una petición AJAX, me sale el siguiente mensaje en la consola de error de javascript:

http://www.blah.com/gmscripts/overrides: in new send 
uncaught exception: [Exception... "Illegal value" nsresult: "0x80070057 (NS_ERROR_ILLEGAL_VALUE)" location: "JS frame :: file:///tmp/customProfileDir41e7266f56734c97a2ca02b1f7f528e1/extensions/%7Be4a8a97b-f2ed-450b-b12d-ee082ba24781%7D/components/greasemonkey.js :: anonymous :: line 372" data: no] 

por lo que parece estar lanzando la excepción al intentar acceder a this.onreadystatechange

Presumiblemente, esto es debido al entorno de espacio aislado. Cualquier ayuda sería muy apreciada. No estoy vinculado a esta solución, por lo que cualquier otra sugerencia para hacer lo que necesito es bienvenida. Es solo que he intentado con varios otros y este parece ser el más prometedor. El requisito es que necesito asegurarme de que el contador llegue a 0 después de, el readyState pasa a 4 y la devolución de llamada onreadystatechange ha finalizado la ejecución.

Respuesta

1

Terminé usando la siguiente:

unsafeWindow.document.ajax_outstanding = 0; 
if (typeof unsafeWindow.XMLHttpRequest.prototype.oldsend != 'function') { 
    unsafeWindow.XMLHttpRequest.prototype.oldsend = unsafeWindow.XMLHttpRequest.prototype.send; 
    unsafeWindow.XMLHttpRequest.prototype.send = function() { 
     unsafeWindow.XMLHttpRequest.prototype.oldsend.apply(this, arguments); 
     this.addEventListener('readystatechange', function() { 
      if (this.readyState == 2) { 
       /* LOADED */ 
       unsafeWindow.document.ajax_outstanding++; 
       console.log('set ajax_outstanding to ' + unsafeWindow.document.ajax_outstanding); 
      } else if (this.readyState == 4) { 
       /* COMPLETED */ 
       unsafeWindow.document.ajax_outstanding--; 
       console.log('set ajax_outstanding to ' + unsafeWindow.document.ajax_outstanding); 
      } 
     }, false); 
    }; 
} 
3

que he hecho algo a mí mismo: http://jsfiddle.net/rudiedirkx/skp28agx/ (actualizado 22 de Ene de 2015)

El guión (debe ejecutar antes de cualquier otra cosa):

(function(xhr) { 
    xhr.active = 0; 
    var pt = xhr.prototype; 
    var _send = pt.send; 
    pt.send = function() { 
     xhr.active++; 
     this.addEventListener('readystatechange', function(e) { 
      if (this.readyState == 4) { 
       setTimeout(function() { 
        xhr.active--; 
       }, 1); 
      } 
     }); 
     _send.apply(this, arguments); 
    } 
})(XMLHttpRequest); 

y escritura de la prueba del jsFiddle:

window.onload = function() { 
    var btn = document.querySelector('button'), 
     active = btn.querySelector('span'); 

    btn.onclick = function() { 
     // jQuery for easy ajax. `delay` is a jsFiddle argument 
     // to keep some requests active longer. 
     jQuery.post('/echo/json/', { 
      delay: Math.random() * 3, 
     }); 
    }; 

    updateActive(); 

    function updateActive() { 
     active.textContent = XMLHttpRequest.active; 
     requestAnimationFrame(updateActive); 
    } 
}; 

Actualiza el contador en el botón de cada cuadro de animación (~ 60 veces por segundo), separado de las solicitudes de AJAX. Hagas lo que hagas, no importa cuán rápido y mucho hagas clic en él, el contador siempre debe terminar en 0 después de unos segundos.

+4

¿realmente le diste una dirección de servidor local o son mis ojos? =)) –

+0

Tenga en cuenta que esta modificación de 'XMLHttpRequest.send' debe instalarse antes de que se envíen las solicitudes AJAX, o el contador podría estar equivocado. Además, creo que sería mejor disminuir 'active' después de llamar a' this._onreadystatechange' (si considera que una solicitud está activa hasta que finalice su controlador de eventos). – seanf

Cuestiones relacionadas