web-dev-qa-db-fra.com

Appels Ajax rapides entraînant l'ignorance de certaines requêtes MySQL

Je travaille actuellement sur un site Web Joomla sur un serveur Unix. Il n'y a aucun utilisateur connecté pour le moment car je suis le seul à pouvoir y accéder (donc pas de trafic lourd).

Au cours des tests, je vais créer plusieurs MySQL INSERTs ou UPDATEs sur une table de ma base de données. Lorsque l'Ajax est déclenché, les données sont envoyées à un fichier php qui se connecte à l'aide de jFactory::getDBO(), exécute une requête et renvoie une réponse de réussite.

Tout fonctionne parfaitement, jusqu'à ce que je lance plusieurs tests en succession rapide. Après un certain temps, même si j'obtiens toujours une réponse de succès dans Ajax, aucune ligne n'est affectée (pas sur cette table, ni sur aucune autre table).

C'est comme si MySQL bloquait toutes les connexions (et pourtant je ne reçois aucun message d'erreur). J'ai essayé d'ouvrir un autre navigateur et comme par magie, les requêtes s'exécutent parfaitement/avec succès à partir de là. Je pense aussi avoir remarqué que cela fonctionne à nouveau lorsque je ferme le navigateur d'origine et que je l'ouvre à nouveau.

Quel pourrait être le problème? Et comment puis-je le résoudre? Je cherchais un moyen de fermer les connexions getDBO() après chaque requête, mais tout ce que j'ai trouvé en ligne, c'est que sur un serveur Unix, ce type de connexion est automatiquement fermé après chaque requête.

Ceci est l'appel 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));   
          }     
});

Voici comment les insertions/mises à jour sont effectuées:

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

Le navigateur reçoit probablement une réponse du cache du navigateur, essayez d’ajouter une variable de temps au lien ou désactivez le cache.

1
Dawid Świtoń

Mon premier souci est toujours la sécurité, add_slashes() est ne fonction inadéquate à appeler pour protéger votre requête . Je vous prie instamment de mettre en œuvre les méthodes de requête Joomla pour construire vos requêtes et lire des informations sur recommandations de sécurité de Joomla .

Je conviens avec les autres volontaires qu’il s’agit probablement d’une question de mise en cache et que MySQL n’est probablement pas le coupable de votre problème. Si MySQL vous posait problème, vous pouvez trouver des preuves dans les journaux des erreurs ou écrire votre fichier php pour renvoyer des commentaires informatifs.

Offrir une plus grande spécificité sur les conseils commentés.

Vous pouvez ajouter une chaîne de requête aléatoire ou temporelle à l'URL/à la page qui reçoit les données soumises de manière à ne jamais avoir deux URL en double:

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

ou

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

Notez que vous n’avez pas réellement besoin d’utiliser $_GET['unique'] Sur la page de destination, c’est simplement utilisé comme identifiant unique pour empêcher la mise en cache.

Si cela ne fonctionne pas ou si vous souhaitez "doubler" la prévention du cache, vous pouvez également écrire header("Cache-Control: no-cache, must-revalidate") tout en haut du fichier php que vous recevez.

Au-delà de tout cela, Joomla a quelques guides sur développer une interface ajax qui sont destinés à améliorer la sécurité et à simplifier le codage.

Et aussi loin que votre condition de validation php brute:

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

Cela peut être réécrit comme if (!empty($step) && trim($step) != "") { parce que !empty() vérifie l'existence (rendant isset() redondant) ET vérifie la valeur non-fausse-y. Si vous attendez moins de la valeur $step, Je vous conseillerais alors d'effectuer une validation plus rigoureuse à cet emplacement dans votre code.

Je ne connais pas les capacités de votre interface de projet, mais si plusieurs soumissions ultérieures (appels ajax) sont probables, vous pourriez peut-être redéfinir le formulaire pour permettre à plusieurs ensembles de données d'être livrés en un seul lot. En minimisant le nombre total d'appels ajax, vous réduisez le nombre de fois qu'une connexion à une base de données doit être ouverte et fermée - c'est la meilleure pratique.

Pour plus de tranquillité d'esprit, vous pouvez renvoyer une explication plus détaillée des valeurs envoyées et du nombre de lignes affectées.

0
mickmackusa