85 votes

JavaScript détecte un événement AJAX

Ok, donc, fondamentalement, je veux avoir un peu de javascript sur une page qui en quelque sorte s'attache à certains type de l'écouteur d'événement qui permet de détecter et de faire quelque chose si une requête ajax (sans possibilité d'appeler directement à partir de l'appel), indépendamment de la façon dont l'appel ajax est faite.

J'ai compris comment le faire avec jquery - si la requête ajax est fait par jquery. Voici un exemple de code:

$.post(
  // requested script
  'someScript.php', 
  // data to send
  {
    'foo' : 'bar',
    'a' : 'b'
  },
  // receive response
  function(response){
    // do something
  }
); // .post

// global event listener    
$(document).ajaxSend(
  function(event,request,settings){
    alert(settings.url); // output: "someScript.php"
    alert(settings.data); // output: "foo=bar&a=b"
  }
);

Avec ce code, peu importe où/comment j'appelle $.la poste(..), le mondial de l'écouteur d'événement de déclenchement. Il fonctionne aussi si j'utilise $.obtenir ou $.ajax (tout jquery ajax méthodes), peu importe comment/quand je l'appelle (jointe à un onclick, au chargement de la page, peu importe).

Cependant, je veux être en mesure d'étendre cet écouteur pour déclencher indépendamment de ce que js cadre est utilisé, ou même si aucun cadre est utilisé. Si, par exemple, je devais aussi avoir sur une page le code suivant (générique ajax code de w3schools):

function loadXMLDoc()
{
if (window.XMLHttpRequest)
  {// code for IE7+, Firefox, Chrome, Opera, Safari
  xmlhttp=new XMLHttpRequest();
  }
else
  {// code for IE6, IE5
  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
xmlhttp.onreadystatechange=function()
  {
  if (xmlhttp.readyState==4 && xmlhttp.status==200)
    {
    document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
    }
  }
xmlhttp.open("GET","test.txt",true);
xmlhttp.send();
}

Et puis j'ai sur certains aléatoire lien un onclick appel à cette fonction, mes ajax écouteur d'événement doit être en mesure de également de détecter cette demande. Eh bien, j'ai ajouté ce code sur ma page et l'ont attaché à un lien menant onclick (oui, le code lui-même), mais le jquery "mondial de l'écouteur d'événement" code ci-dessus n'a pas pu détecter cet appel.

J'ai fait un peu plus de creuser et je sais que je peux fondamentalement enregistrer l'objet d'une température de l'objet et de remplacer l'actuel objet avec un "wrapper" de l'objet qui va appeler une fonction spécifiée, puis d'appeler la temp de la fonction, mais cela m'oblige à connaître à l'avance de l'objet d'origine en cours de création/d'occasion. Mais je ne le sait pas toujours que l'avance de temps...

Alors...est-ce possible? Est-il possible de détecter un ajax get/post demande a été faite, indépendamment du fait qu'il a été fait avec un objet générique ou de xyz cadre? Ou suis-je tout simplement allez devoir faire dupliquer le code pour gérer chaque cadre et de connaître à l'avance l'ajax d'objet(s) en cours de création/d'occasion?

edit:

J'ai oublié de mentionner qu'il ne suffit pas de détecter qu'une demande avait été faite. J'ai aussi besoin de capturer les données envoyées dans la requête. Le lien fourni dans les commentaires ci-dessous aidera à savoir si "une" demande a été faite, mais de ne pas obtenir les données envoyées. p.s. - la réponse dans le lien ci-dessous n'est pas très clair, au moins pour moi, de toute façon.

117voto

Crayon Violent Points 16544

Ok c'est ce que j'ai à ce jour:

<script type='text/javascript'>
var s_ajaxListener = new Object();
s_ajaxListener.tempOpen = XMLHttpRequest.prototype.open;
s_ajaxListener.tempSend = XMLHttpRequest.prototype.send;
s_ajaxListener.callback = function () {
  // this.method :the ajax method used
  // this.url    :the url of the requested script (including query string, if any) (urlencoded) 
  // this.data   :the data sent, if any ex: foo=bar&a=b (urlencoded)
}

XMLHttpRequest.prototype.open = function(a,b) {
  if (!a) var a='';
  if (!b) var b='';
  s_ajaxListener.tempOpen.apply(this, arguments);
  s_ajaxListener.method = a;  
  s_ajaxListener.url = b;
  if (a.toLowerCase() == 'get') {
    s_ajaxListener.data = b.split('?');
    s_ajaxListener.data = s_ajaxListener.data[1];
  }
}

XMLHttpRequest.prototype.send = function(a,b) {
  if (!a) var a='';
  if (!b) var b='';
  s_ajaxListener.tempSend.apply(this, arguments);
  if(s_ajaxListener.method.toLowerCase() == 'post')s_ajaxListener.data = a;
  s_ajaxListener.callback();
}
</script>

DIRECTIONS:

Juste c/p cela sur votre page ou l'inclure dans une .fichier js ou quoi que ce soit. Cela va créer un objet appelé s_ajaxListener. Chaque fois qu'une requête AJAX requête GET ou POST est fait, s_ajaxListener.callback() est appelée, et les propriétés suivantes sont disponibles:

s_ajaxListener.méthode : L'ajax méthode utilisée. Ce sera soit GET ou POST. REMARQUE: la valeur peut ne pas toujours être en majuscule, cela dépend de la façon dont la demande a été codé. Je suis en train de débattre de la sagesse de automatiquement les haut-emboîtage, ou en le laissant à quelque chose d'autre à toLowerCase() pour une comparaison sensible à la casse.

s_ajaxListener.url : L'url du script demandé (y compris la chaîne de requête, le cas échéant) (urlencoded). J'ai remarqué, en fonction de la façon dont les données sont envoyées et à partir de laquelle navigateur/cadre, par exemple, cette valeur pourrait être que "" ou "+" ou "%20". Je suis en train de débattre de la sagesse de décodage ici, ou laisser quelque chose d'autre.

s_ajaxListener.données : les données transmises, le cas échéant ex: foo=bar&a=b (même 'problème'.url avec l'url-encodé)

NOTES:

Comme il est, ce n'est pas compatible IE6. cette solution n'est pas tout à fait assez bon pour moi, que je veux qu'il soit compatible IE6. Mais depuis, beaucoup d'autres personnes ne se soucient pas de IE6, j'ai décidé de poster ma solution dans son état actuel, car il doit travailler pour vous si vous n'avez pas de soins sur IE6.

J'ai testé ce dans le (date): Courant Safari, Actuelle de Chrome, FireFox Courant, IE8, IE8 (Compatible IE7). Il ne fonctionne actuellement pas avec IE6 parce que IE6 utilise un objet ActiveX, alors que pratiquement tout le reste utilise XMLHttpRequest.

Droit maintenant, je n'ai pas la moindre idée de comment, eh bien au fond de prototype/étendre/surcharge (?) ActiveXObject("Microsoft.XMLHTTP"). C'est ce que je suis actuellement à la recherche...quelqu'un sait désinvolte?

En vertu de chacun des navigateurs que j'ai testé ci-dessus, cela fonctionne avec des requêtes AJAX à partir d'un objet générique, et aussi de l'jquery et prototype de cadres. Je sais qu'il y a d'autres cadres, mais, de l'OMI ces 2 sont les plus importants. Je pourrais éventuellement QA MooTools, mais à part ça, je suis très bien avec un seul test.

Si Quelqu'un veut contribuer par des essais et à publier les résultats sur les autres navigateurs et/ou des cadres, il serait apprécié :)

5voto

Pour la compatibilité avec IE 6, que diriez-vous:

 <script type='text/javascript'>
  var s_ajaxListener = new Object();

  // Added for IE support
  if (typeof XMLHttpRequest === "undefined") {
    XMLHttpRequest = function () {
      try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); }
      catch (e) {}
      try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); }
      catch (e) {}
      try { return new ActiveXObject("Microsoft.XMLHTTP"); }
      catch (e) {}
      throw new Error("This browser does not support XMLHttpRequest.");
    };
  }

  s_ajaxListener.tempOpen = XMLHttpRequest.prototype.open;
  s_ajaxListener.tempSend = XMLHttpRequest.prototype.send;
  s_ajaxListener.callback = function () {
    // this.method :the ajax method used
    // this.url    :the url of the requested script (including query string, if any) (urlencoded) 
    // this.data   :the data sent, if any ex: foo=bar&a=b (urlencoded)
  }

  XMLHttpRequest.prototype.open = function(a,b) {
    if (!a) var a='';
    if (!b) var b='';
    s_ajaxListener.tempOpen.apply(this, arguments);
    s_ajaxListener.method = a;  
    s_ajaxListener.url = b;
    if (a.toLowerCase() == 'get') {
      s_ajaxListener.data = b.split('?');
      s_ajaxListener.data = s_ajaxListener.data[1];
    }
  }

  XMLHttpRequest.prototype.send = function(a,b) {
    if (!a) var a='';
    if (!b) var b='';
    s_ajaxListener.tempSend.apply(this, arguments);
    if(s_ajaxListener.method.toLowerCase() == 'post')s_ajaxListener.data = a;
    s_ajaxListener.callback();
  }
</script>
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X