0

MySQL データベースに大量のデータを挿入する XMLHttpRequest があり、5 ~ 10 秒かかります。リクエストのコードは次のとおりです。

function sendRequest(url, params, divToChange)
{
   // code for IE7+, Firefox, Chrome, Opera, Safari
   if (window.XMLHttpRequest)
   {
       var httpRequest = new XMLHttpRequest();
   }      
   else // code for IE6, IE5
   {
       var httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
   }

   // Stage 3 - open the request and prepare variables for the PHP method being  
      activated on server side//
   httpRequest.open("POST", url, true); 

   //Set request headers for POST command//
   httpRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
   httpRequest.setRequestHeader("Content-length", params.length);
   httpRequest.setRequestHeader("Connection", "close");

   httpRequest.onreadystatechange=function()
   {
       if(httpRequest.readyState==3)
       {     
           document.getElementById(divToChange).innerHTML='please wait';
       }
       if(httpRequest.readyState==4 && httpRequest.status==200)
       {
           document.getElementById(divToChange).innerHTML=httpRequest.responseText;
       }
   }

   httpRequest.send(params); // Stage 4 - sending the request to the server//

   //end when the server will responde we will execute the        
   "document.getElementById("txtHint").innerHTML=xmlhttp.responseText;" //

}

//Calling the request with this function//
function createEventList() 
{   

   var url = "grid-update_event_list.php";
   var params = "firstLoad=1";

   //Create the httpRequest and send it to the server//
   sendRequest(url,params, "eventsList");  
}

そして、これは応答テキストを取得するために私のhtmlで定義されています:

<p>Events List Status: <b id='eventsList'>  </b></p>

ブラウザの 2 つの動作を理解できません。

1-「しばらくお待ちください」というテキストがブラウザに表示されません。何が起こっているのかをテストするために を追加するalert(httpRequest.readyState)と、予想どおり「3」のポップアップが表示されましたが、 に移動した直後にreadyState==3それが見られましたreadyState==4。それらは同時に起こっているようです。httpRequest.responseText;of で返されたテキストが表示されますreadyState==4

2-リクエストを送信した後、別のページに移動できません。現在のページは応答しています(コンボボックスを変更できます)が、別のリンクに移動しようとすると、ブラウザはreadyState = = 4まで待機し、それからリンクに進みます。リクエストが として定義されているため、それも理解できませんasynchronous = true

これらの2つの動作を引き起こす何か間違ったことをしていますか? ありがとう。

4

2 に答える 2

2

1.- ajax 呼び出しの準備状態を理解する必要があります。5 つの異なる準備状態があります。詳細については、次のリンクを参照してください。

ReadyStates

したがって、別の readystate (私は 1 または 2 を使用します) を使用して、リクエストの開始時にダイアログを表示できます。それ以外の場合は、httpRequest を送信する前に div を変更してください。

2.- ajax 呼び出しが非同期であっても、シーケンシャルです。つまり、リクエストを送信すると、そのリクエストの応答を受信するまで、別のリクエストを送信できません。ページの変更は別の要求/応答サイクルであるため、最初の要求の応答を受け取るまでページを変更することはできません。

お役に立てれば...

于 2012-05-17T09:58:30.870 に答える
2

この記事を見つけて、本当にがっかりしました。21 世紀に、非同期のバックグラウンド リクエストがブラウザ全体のナビゲーションをどのようにブロックできたのでしょうか。意味がありません。誰かが今までにこれを修正しているはずです。

結局のところ、少なくとも私の場合、それはブラウザーではありません。ブラウザには同時リクエストの数に制限があり、通常は 6 程度です。しかし、それは悪意のある Web ページによる DoS 攻撃を防ぐためのものです。本当の問題はPHPです。

PHP がデフォルトのファイルベースのセッション システムを使用している場合、セッションは、ページが終了するか、session_write_close() の呼び出しによって閉じられるまでロックされます。

何が起こっているかというと、ベース ページがセッションを開き、その処理を実行してから閉じます。ここで、ブラウザーはページの一部に何かを AJAX で挿入したいと考え、ベース ページを配信した同じサーバーにコールバックします。このサーバーは、セッションを再開し、AJAX 処理が完了するまで開いたままにします。その間、同じセッションで同じサーバーからいくつかのコンテンツを動的にロードしたいページの別のセクションがあります。PHP は、「いいえ、待つ必要があります。セッションは他の人によって既に開かれています」と言います。最初の AJAX がセッションを閉じるとすぐに、2 番目の AJAX が通過し、その役割を果たします。ここで、最初の通話に 15 分かかるとします。同じセッションを使用した同じサーバーへの 2 番目の呼び出しとリンク クリックは、それ以前に発生したすべての読み込みとクリックなどが完了するまでブロックされます。悪夢!ページが凍結され、AJAX 呼び出しが順番に実行されているように見えます。しかし、ブラウザーや XmlHttpRequest が原因ではありません。

どうすればこれを修正できますか? 簡単な方法は、ヒットして実行することです。ページがコードの最初の数行を超えてセッションに読み書きする必要がない場合は、データを取得したら、session_write_close() を呼び出します。これでセッションのロックが解除され、他の人が使用できるようになります。この次の部分について推測していますが、うまくいくと思います。後でセッションに書き込む必要がある場合は、開いたままにするのではなく、他の人が使用できるように閉じてから、セッション ID を保存し、後で session_start($id) を使用して再度開きます。

より難しい方法は、ロックしない独自のセッション ハンドラーを作成することです。これは実際に私がしたことです。ロックしない Cassandra ベースのセッション ハンドラがあります。欠点は、「Last in wins」の同時実行の影響を受けることですが、私の場合、実際にセッションに書き込むのは基本ページのみであり、AJAX 呼び出しは何も書き込まないため、問題にはなりません。ハンマーがなければデータを壊すことはできません。

元の回答は私の問題を解決するのに役立ちましたが、実際に何が起こっているのかについての完全な誤解であるため、これが役立つことを願っています. 非同期 XmlHttpRequests はシーケンシャルではありません。

于 2018-08-18T00:02:52.960 に答える