web-dev-qa-db-ja.com

一部のMySQLクエリが無視される原因となる高速のAjax呼び出し

現在、Unixサーバー上のJoomla Webサイトで作業しています。アクセスできるのは私だけなので、現時点で接続しているユーザーはいません(大量のトラフィックはありません)。

テスト中、DBのテーブルにいくつかのMySQL INSERTsまたはUPDATEsを作成します。 Ajaxがトリガーされると、jFactory::getDBO()を使用して接続し、クエリを実行して成功応答を返すphpファイルにデータが送信されます。

いくつかのテストを連続して実行するまで、すべてが完璧に機能します。しばらくすると、Ajaxで引き続き成功の応答が返されますが、影響を受けた行はありません(このテーブルではなく、他のテーブルにもありません)。

MySQLがすべての接続をブロックするようなものです(それでもエラーメッセージは表示されません)。別のブラウザーを開いてみたところ、魔法のようにそこからクエリが完全に/成功して実行されました。また、元のブラウザを閉じてもう一度開くと、再び動作し始めていることに気づいたと思います。

問題は何でしょうか?そして、どうすれば解決できますか?各クエリの後にgetDBO()接続を閉じる方法を探していましたが、オンラインで見つかったのは、Unixサーバーでは、このタイプの接続が各クエリの後に自動的に閉じられることです。

これはAjax呼び出しです。

jQuery.ajax({
          type:"POST",
          url:"/models/ajax.php",
          data:{"sid":sid, "steid":steid, "answer":answer,   "function_to_call":21},
          dataType: "json",
          cache: false,
          success: function(data){
              console.log(JSON.stringify(data));
          },
          error: function(msg){
            console.log(JSON.stringify(msg));   
          }     
});

これは挿入/更新が実行される方法です:

if(isset($step) && !empty($step) && trim($step) != ""){

  $sql = "UPDATE #__thamatho_student_mistakes SET   
  date_mistake='".$date."', answer='".addslashes($answer)."' WHERE 
  student=".$userid." and step=".$steid;
  $db->setQuery($sql);
  $db->query();

}else{  

  $sql = "Insert into #__thamatho_student_mistakes (`student`, 
  `step`, `answer`, `date_mistake`) values (".$userid.", ".$steid.", 
  '".addslashes($answer)."', '".$date."')";
  $db->setQuery($sql);
  $db->query();

}
5
user3716433

おそらくブラウザはブラウザのキャッシュから応答を受け取ります。リンクに時間変数を追加するか、そうでなければキャッシュを無効にしてください

1
Dawid Świtoń

私の最初の懸念は常にセキュリティです。add_slashes()クエリを保護するために呼び出すには不十分な関数 です。 Joomlaクエリメソッド を実装してクエリを作成し、 Joomlaのセキュリティ推奨事項 について読むことをお勧めします。

これはキャッシングの問題である可能性が高く、MySQLが問題の原因ではない可能性があることを他のボランティアに同意します。 MySQLで問題が発生した場合、エラーログで証拠を見つけたり、phpファイルを書き込んで有益なフィードバックを返すことができます。

コメントされたアドバイスをより具体的に提供するため。

ランダムまたは時間ベースのクエリ文字列を、送信されたデータを受信するURL /ページに追加して、2つの重複したURLが存在しないようにすることができます。

_url:"/models/ajax.php?unique=" + Math.random(),
_

または

_url:"/models/ajax.php?unique=" + +new Date();
_

受信ページで実際にuse_$_GET['unique']_する必要はないことに注意してください。これは、キャッシュを防ぐための一意の識別子として使用されているだけです。

それが機能しない場合、またはキャッシュ防止を「ダブルダウン」したい場合は、受信phpファイルの最上部にheader("Cache-Control: no-cache, must-revalidate")を書き込むこともできます。

そのすべてに加えて、Joomlaには ajaxインターフェースの開発 に関するいくつかのガイドがあり、セキュリティを向上させ、コーディングを簡単にすることを目的としています。

そして、あなたの生のPHP検証条件まで:

_if(isset($step) && !empty($step) && trim($step) != ""){
_

if (!empty($step) && trim($step) != "") {は存在をチェックし(!empty()を冗長にする)、偽でないy値をチェックするため、これはisset()に書き換えることができます。 _$step_値に対する期待がより狭い場合は、コード内のこの場所でより強力な検証を実行することをお勧めします。

あなたのプロジェクトインターフェースの機能はわかりませんが、その後の複数の送信(ajax呼び出し)が考えられる場合は、フォームを再設計して、複数のデータセットを1つのバッチで配信できるようにすることができます。 ajax呼び出しの総数を最小限に抑えることで、db接続を開いたり閉じたりする必要がある回数を最小限に抑えることができます。これがベストプラクティスです。

安心感を高めるには、送信された値と影響を受けた行数の詳細な説明を返すことができます。

0
mickmackusa