Maison > Article > interface Web > Problème de compatibilité du téléchargement de fichiers lors d'une requête Ajax sous le navigateur FireFox
J'ai récemment travaillé sur un projet, et l'une des exigences du projet était la suivante. Cliquez sur un lien de fichier pour télécharger le fichier, et en même temps envoyez une demande en arrière-plan. Il y a eu de nombreux problèmes pendant le processus de développement. L'éditeur a partagé un résumé des problèmes sur la plateforme Script Home Pour votre référence
L'exigence est très simple, cliquez sur un lien de fichier pour télécharger le fichier et envoyer une requête en arrière-plan en même temps. La demande est très courante. Une fois que les utilisateurs ont cliqué pour télécharger, ils doivent généralement compter le volume de téléchargement. Pour les statistiques, vous pouvez utiliser les capacités inter-domaines des balises de script ou des balises img (ping d'image) pour pointer leurs attributs src vers les statistiques. adresse. Mais cette fois, c'est ajax qui est utilisé. Selon les statistiques, ce problème se pose.
Le code de démonstration est le suivant :
<a id="a" href="http://c758482.r82.cf2.rackcdn.com/Sublime Text 2.0.2 x64 Setup.exe" >click</a> <script src="jQuery.js"></script> <script> document.getElementById("a").onclick = function(e) { $.post("data.php"); }; </script>
Nous savons tous que si une balise a a à la fois un événement onclick et un attribut href, le rappel de l'événement onclick sera être dans l'événement par défaut ( (c'est-à-dire sauter) avant l'exécution, c'est pourquoi vous pouvez utiliser un code similaire à e.preventDefault() dans l'événement onclick pour supprimer l'événement par défaut (c'est-à-dire sauter). Par conséquent, si vous cliquez sur la balise a dans le code ci-dessus, le rappel de l'événement onclick sera d'abord exécuté, c'est-à-dire qu'une requête ajax sera envoyée. En théorie, car l'ajax dans le code est asynchrone (en fait, le code ajax est asynchrone). il en va de même pour la synchronisation), le fichier téléchargé sera ouvert lors de la demande.
Les performances dans les navigateurs Chrome, UC, Opera et 2345 sont conformes aux attentes. En cliquant sous Firefox, vous pouvez sauter pour télécharger le fichier, mais la partie ajax signale une erreur. Elle n'a pas été testée sous IE.
Au début, la mauvaise idée était que le cross-domain provoquerait des erreurs. Lorsque vous cliquez sur le lien de téléchargement, la requête ajax pensera que la page est sur le point d'accéder à l'adresse indiquée par le href, ce qui amènera le navigateur à penser que l'ajax est multi-domaine. Cette idée fausse a été rapidement renversée. Premièrement, parce que la requête ajax a été effectuée en premier, la requête ne traversait pas le domaine pour le moment ; deuxièmement, aucune erreur inter-domaine n'a été signalée (généralement la console indiquera s'il s'agit d'une erreur inter-domaine). erreur); troisièmement, le code suivant a été mis à jour. Preuve supplémentaire de l'erreur.
<a id="a" href="http://c758482.r82.cf2.rackcdn.com/Sublime Text 2.0.2 x64 Setup.exe" >click</a> <script src="jQuery.js"></script> <script> $.post("data.php"); // data.php sleep(100) </script>
Ouvrez la page et faites une requête ajax. Une fois le bouton de téléchargement cliqué, la requête est abandonnée. Si la valeur de l'attribut href de la balise a n'est pas une adresse de fichier, mais remplacée par n'importe quelle URL, si vous cliquez sur la balise a, la page passera immédiatement à l'adresse pointée par la balise et la page n'existera plus, et ajax sera naturellement interrompu. Si la balise a pointe vers une adresse de fichier, sera-t-elle analysée de la même manière sous ff (le navigateur pense qu'il va accéder à cette adresse et termine ajax) ?
La réponse est oui, j'ai trouvé la réponse sur stackoverflow.
Lorsque vous cliquez sur le lien de téléchargement, vous quittez la page, même si cela ne semble pas être le cas. S'il n'y avait pas de transfert de fichier, vous verriez la page demandée. Essayez de définir un target="_blank" ou d'utiliser. une iframe comme cible pour le lien.
Comme le montre la question, Chrome et ff ont eu des problèmes similaires en 2010, et les navigateurs basés sur Chrome ou Webkit l'ont corrigé dans les itérations de versions suivantes, ff a laissé ce problème jusqu'à ce que maintenant (je pense personnellement que c'est déraisonnable).
Lorsque vous connaîtrez la racine du problème, la solution apparaîtra facilement.
Méthode 1 :
La méthode la plus simple consiste à ajouter target="_blank" à la balise a. En fait, c'est généralement ainsi que les pages Web procèdent. est aussi une démarche digne de reconnaissance.
Méthode 2 :
Puisque le comportement par défaut de la balise a interrompra la requête ajax, que diriez-vous de mettre le « comportement par défaut » avant la requête ?
<a id="a" href="javascript:;" >click</a> <script src="jQuery.js"></script> <script> document.getElementById("a").onclick = function(e) { location.href = "http://c758482.r82.cf2.rackcdn.com/Sublime Text 2.0.2 x64 Setup.exe"; $.post("data.php"); }; </script>
Méthode 3 :
Définir une minuterie pour retarder la requête, mais parce que le saut par défaut de la balise a n'est pas dans la portée du fil Javascript , ce Le réglage du seuil de retard est très important. Le résultat de mon test local était en fait de 2 ms (ce à quoi je ne m'attendais pas. Généralement, le régler à environ 100 ms est correct). Cette méthode est inélégante et ne doit pas être utilisée.
<a id="a" href="http://c758482.r82.cf2.rackcdn.com/Sublime Text 2.0.2 x64 Setup.exe" >click</a> <script src="jQuery.js"></script> <script> document.getElementById("a").onclick = function(e) { setTimeout(function() { $.post("data.php"); }, 100); }; </script>
J'ai compilé ce qui précède pour vous, j'espère que cela vous sera utile à l'avenir.
Articles connexes :
Méthode d'implémentation Ajax pour l'ajout dynamique de données à la liste déroulante
Implémentation Ajax de l'enregistrement et du téléchargement après la sélection avatar
Détailler les différences entre async:false et async:true dans les requêtes Ajax
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!