1. ホーム
  2. javascript

AJAXイベントを検出するJavaScript

2023-07-19 04:04:29

質問

さて、基本的に私は、ajaxの呼び出しがどのように行われるかにかかわらず、ajaxの要求が行われた場合(呼び出しからそれを直接呼び出さずに)検出し、何かを行うことができる何らかの種類のグローバルイベントリスナーを取り付けるページ上のjavascriptのビットを持っていたいのです。

私はjqueryでこれを行う方法を考え出しました - もしajaxリクエストが行われているのであれば によって jqueryで行います。以下は、そのためのコード例です。

$.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"
  }
);

このコードでは、どこでどのように$.post(...)を呼んでも、グローバルイベントリスナーはトリガーされます。また、$.getや$.ajax(あらゆるjquery ajaxメソッド)を使用した場合も、いつどのように呼び出すか(onclickとして添付、ページロード時、何でも)に関係なく、動作します。

しかし、私は、どのようなjsフレームワークが使用されているか、またはフレームワークが使用されていない場合でも、トリガーするためにこのリスナーを拡張できるようにしたいと思います。 例えば、私が は、次のコード(w3schoolsからの一般的なAjaxコード)をページ上に持っています。

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();
}

そして、ランダムなリンクにその関数へのクリックを呼び出すと、グローバルなajaxイベントリスナーは、次のようなことができるはずです。 また はこの要求を検出します。 さて、私はそのコードを私のページに追加し、ランダムなリンクのonclick(はい、コード自体は動作します)に取り付けましたが、上記のjquery "global event listener"のコードはその呼び出しを検出することができませんでした。

さらに調べてみたところ、基本的にオブジェクトを temp オブジェクトに保存し、指定された関数を呼び出してから temp 関数を呼び出す "wrapper" オブジェクトで現在のオブジェクトを上書きできますが、これには、作成/使用される元のオブジェクトを前もって知っておく必要があります。しかし、私は常に前もってそれを知っているわけではありません...。

では...これは可能なのでしょうか?一般的なオブジェクトで行われたか、xyzフレームワークから行われたかにかかわらず、ajax get/postリクエストが行われたことを検出する何らかの方法がありますか? それとも、それぞれのフレームワークを処理するために重複したコードを作成し、また、作成/使用されるajaxオブジェクトを前もって知る必要があるのでしょうか?

編集してください。

言及するのを忘れていましたが、リクエストが発生したことを検出するだけでは不十分です。また、リクエストで送信されたデータをキャプチャする必要があります。 以下のコメントで提供されたリンクは、リクエストが行われたかどうかを把握するのに役立ちますが、送信されたデータを取得することはできません。 p.s. - 以下のリンクで提供された回答は、少なくとも私には、あまり明確ではありません。

どのように解決するのですか?

さて、ここまでが私が思いついたことです。

<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:

これをあなたのページにc/pするか、.jsファイルか何かにインクルードしてください。これは、s_ajaxListenerと呼ばれるオブジェクトを作成します。AJAXのGETやPOSTのリクエストがあると、s_ajaxListener.callback()が呼び出され、以下のプロパティが利用できるようになります。

s_ajaxListener.method : 使用されるajaxメソッド。これはGETまたはPOSTのいずれかであるべきです。注:値は常に大文字であるとは限りません、それは特定のリクエストがどのようにコード化されたかに依存します。自動的に大文字にするか、大文字小文字を区別しない比較のためにtoLowerCase()に他のものに任せるか、その知恵を議論しているところです。

s_ajaxListener.url : 要求されたスクリプトの URL (もしあれば、クエリ文字列を含む) (urlencoded) です。私は、データがどのように送信され、どのブラウザ/フレームワークからかによって、例えばこの値は " " または "+" または "%20" のように終わることができることに気づきました。 私は、この値をここでデコードするか、他のものに任せるか、その知恵を議論しています。

s_ajaxListener.data : もしあれば、送られたデータ 例: foo=bar&a=b (url-encodeされた.urlと同じ「問題」)

NOTES:

現状では これはIE6互換ではありません .この解決策は、IE6互換であることを望む私にとっては、全く十分ではありません。しかし、他の多くの人々はIE6を気にしないので、IE6を気にしないのであれば、私の解決策はうまくいくはずなので、現状のまま投稿することにしました。

でテストしてみました。 (この投稿日現在)。現在の Safari、現在の Chrome、現在の FireFox、IE8、IE8 (IE7 Compatible) でテストしています。IE6 では ActiveX オブジェクトを使用し、他のほぼすべてが XMLHttpRequest を使用するため、現在 IE6 では動作していません。

今のところ、基本的に ActiveXObject("Microsoft.XMLHTTP") をプロトタイプ/拡張/オーバーロード (?) する方法について、何の手がかりも持っていないのです。これは、私が現在研究していることです...誰か直接知っていますか?

私が上でテストした各ブラウザの下では、これは一般的なオブジェクトからの AJAX リクエストで、また、jquery および prototype フレームワークからも動作します。他のフレームワークがあることは知っていますが、IMO はこれら 2 つが主要なものです。 MooToolsのQAをするかもしれませんが、それ以外は、これらのテストだけで結構です。

もし誰かが他のブラウザやフレームワークについてテストし、結果を投稿することで貢献したいのであれば、それはありがたいことです :)