IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

AJAX Discussion :

[AJAX] Interrompre requete ajax


Sujet :

AJAX

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 13
    Par défaut [AJAX] Interrompre requete ajax
    Bonjour,

    Dans certains cas de figure, je souhaite interrompre une requête ajax avant d'en lancer une nouvelle (la requête en cours peut prendre du temps à s'exécuter côté serveur).
    Pour faire ceci, j'exécute une méthode cancel() sur ancienne requête (framework mootools), et je lance la nouvelle. La partie javascript se passe bien mais j'ai l'impression qu'il y a un soucis côté serveur.
    Même si la première requête a été annulée, le traitement continue sur le serveur. Du coup, ma seconde requete est en stand by jusqu'à ce que la première soit terminée... ce qui anéantit tout le bénéfice de l'annulation de la première requête.

    Est-ce que vous avez déjà rencontré ce problème, et est-ce que vous avez des pistes ?

    Merci d'avance

  2. #2
    Membre Expert
    Avatar de emmanuel.remy
    Inscrit en
    Novembre 2005
    Messages
    2 855
    Détails du profil
    Informations personnelles :
    Âge : 56

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 855
    Par défaut
    Salut,

    Il y a la possibilité de détecter côté server si la connexion est encore active.
    Comme tu n'indiques pas le langage Server, je vais te prendre un exemple en PHP.

    En PHP on dispose d'une fonction ignore_user_abort(true/false) qui autorise un script à s'interrompre sur appui du bouton STOP du navigateur ou sur appel de la fonction abort de XMLHttpRequest. Ensuite on peut jouer avec les fonctions connection_aborted et connection_status.

    Je te passe deux exemples de script cibles d'un appel Ajax, vérifiés, selon ignore_user_abort(true/false):

    D'abord celui qui n'interrompt pas le script en cas d'arrêt:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    <?php
    /*
     * La sortie qui aura lieu dans le log
     * 
     * [01-Nov-2009 17:17:57] STATUS ABORT détecté
     * [01-Nov-2009 17:17:57] Traitement de la connection interrompue après 7 boucles
     *  
     */
     
    //on autorise le script à continuer même si l'utilisateur l'interrompt
    ignore_user_abort(true);
     
    $i=0;
    function end_script() {
    	global $i;
    	//si la conenction est en status ABORT
    	switch (connection_status()) {
    		case 1:
    			error_log("Traitement de la connection interrompue après $i boucles");
    			break;
    		case 2:
    			error_log("Traitement du timeout du script");
    			break;
    	}
    }
    //on enregistre la fonction
    register_shutdown_function("end_script");
     
    for ($i=0; $i<10;$i++) {
    	//temporisation
    	usleep(400 * 1000);
    	//Il faut envoyer des données vers le client pour que PHP 
    	//détecte un changement d'état de connexion
    	//Attention à ce que par défaut output_buffering ne soit pas sur 'on'
    	echo ("\n");
    	//vide le tampon de sortie (à tester car ob_flush() peut être aussi utile,
    	//notamment selon la plate-forme (Windows, Unix...)
    	flush();
    	if (connection_aborted()) {
    		error_log("STATUS ABORT détecté");
    		die();
    	}
    }
     
     
    echo("Envoi normal des données");
    ?>
    Ensuite celui qui l'interrompt:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    <?php
     
    /*
     * La sortie qui aura lieu dans le log
     * 
     * [01-Nov-2009 17:22:44] Traitement de la connection interrompue après 6 boucles
     *  
     */
     
    /*
     * On n'autorise pas le script à continuer si l'utilisateur l'interrompt
     * Pour autant, toute fonction enregistrée par un register_shutdown_function
     * sera quand même appelée
     * 
     * [01-Nov-2009 17:22:44] Traitement de la connection interrompue après 6 boucles
     * 
     */
    ignore_user_abort(false);
     
    $i=0;
    function end_script() {
            global $i;
            //si la conenction est en status ABORT
            switch (connection_status()) {
                    case 1:
                            error_log("Traitement de la connection interrompue après $i boucles");
                            break;
                    case 2:
                            error_log("Traitement du timeout du script");
                            break;
            }
    }
    //on enregistre la fonction
    register_shutdown_function("end_script");
     
    for ($i=0; $i<10;$i++) {
            //temporisation
            usleep(400 * 1000);
            //Il faut envoyer des données vers le client pour que PHP 
            //détecte un changement d'état de connexion
            //Attention à ce que par défaut output_buffering ne soit pas sur 'on'
            echo ("\n");
            //vide le tampon de sortie (à tester car ob_flush() peut être aussi utile,
            //notamment selon la plate-forme (Windows, Unix...)
            flush();
    }
     
     
    echo("Envoi normal des donnees");
    ?>
    Dans les autres langages la démarche peut-être un peu différente, par exemple en Java où il faut s'attendre à catcher une exception liée à l'impossibilité d'écrire dans le flux de sortie s'il a été fermé (erreur habituelle: Connection reset by peer: socket write error)

    ERE

  3. #3
    Expert éminent

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    13 474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2007
    Messages : 13 474
    Par défaut
    Bonjour,
    côté JavaScript, tu peux essayer A+

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 13
    Par défaut
    Bonsoir, et merci d'avoir pris du temps pour me répondre.

    @E.Bzz : Quand j'ai exposé mon problème, j'ai indiqué que j'utilisais le framework mootools. La fonction cancel() de mon objet xhr correspond à la fonction abort() d'autres frameworks. Pour les exemples suivant, j'utilise jQuery, ce sera plus simple.

    @emmanuel.remy J'ai fais pas mal de tests à partir du code que tu m'as donné, sans avoir le résultat que je souhaite. Je suis donc reparti de zéro, et là, je me retrouve face à une bizarrerie...

    Explications : J'ai un projet basé sur le Zend Framework. J'ai une page quelconque avec un lien js qui fait un appel ajax sur un controller de mon application.

    Voici le JS (jQuery) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    var xhr1 = false;
     
    function testAjax1(e)
    {
    	closeXhr1();
    	e.preventDefault(); 
     
    	xhr1 = $.get("test/test", function(data){
     
    		  alert("Data Loaded: " + data);
    	});
     
    }
     
    function closeXhr1()
    {
    	if(xhr1 !== false)
    	{
    		console.log('xhr 1 abort');
    		xhr1.abort();
    		xhr1 = false;
    	}
    }
    Et voici mon action sur le serveur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    	public function testAction()
    	{
    		for ($i=0; $i<10;$i++) {
    			sleep(1);
    		}
    		echo 'envoie données';
    		exit;
    	}
    Lorsque je click sur le lien, la requête ajax se lance, et 10sec plus tard j'ai mon alert. Normal.Si je clique deux fois de suite (la première requête est annulée), il me faut attendre 20sec pour avoir le alert, ce qui veut dire que je suis allé au bout de ma première action, même si elle est annulée. De ce que j'ai compris, ce comportement est normal.

    Mais j'ai fais un autre test. Au lieu d'appeler une action de mon controller ZF, j'appelle un simple script de test.
    Le code JS (identique au premier, sauf pour l'url) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    var xhr2 = false;
     
    function testAjax2(e)
    {
    	closeXhr2();
    	e.preventDefault(); 
     
    	xhr2 = $.get("test.php", function(data){
    		 alert("Data Loaded: " + data);
    	});
     
    }
     
    function closeXhr2()
    {
    	if(xhr2 !== false)
    	{
    		console.log('xhr 2 abort');
    		xhr2.abort();
    		xhr2 = false;
    	}
    }
    Et le code de mon fichier test.php, tout simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    for ($i=0; $i<10;$i++) {
    	sleep(1);
     
    }
     
    echo("Envoi normal des donnees");
    Et bien dans ce cas, si j'ai deux requêtes successives, dans tout les cas j'ai ma réponse après 10s, et non pas 20...

    Est-ce que vous avez une idée du pourquoi du comment ?!
    J'ai joué avec le ignore_user_abort dans les deux cas, et ça ne change rien...
    J'ai besoin de vos lumières sur ce coup !

    Merci d'avance.

  5. #5
    Membre Expert
    Avatar de emmanuel.remy
    Inscrit en
    Novembre 2005
    Messages
    2 855
    Détails du profil
    Informations personnelles :
    Âge : 56

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 855
    Par défaut
    Salut,

    Lorsque je click sur le lien, la requête ajax se lance, et 10sec plus tard j'ai mon alert. Normal.Si je clique deux fois de suite (la première requête est annulée), il me faut attendre 20sec pour avoir le alert, ce qui veut dire que je suis allé au bout de ma première action, même si elle est annulée. De ce que j'ai compris, ce comportement est normal.
    Pas vraiment normal. Car si tu fermes ta requête AJAX, cela ne t'empêche pas d'en exécuter une autre de suite. Ce qui peut continuer de s'exécuter c'est le script sur le server, mais je ne vois pas pourquoi cela interdirait de faire une seconde requête.
    Donc autant ton second cas de figure est normal, autant ce premier cas avec ZEND est étrange; Zend dispose-t-il d'un système qui bloque d'une manière ou d'une autre la seconde exécution d'une action tant que la première n'est pas finie ?

    ERE

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 13
    Par défaut
    Après de nouveaux tests, il s'avere que le probleme ne vient pas de zend, mais des sessions.
    Dès lors que j'ai une session, je vais systématiquement au bout de mon script. Je suis tombé sur un article qui à l'air intéréssent, mais je n'ai pas fini de le lire...

    http://www.chipmunkninja.com/Trouble...ax-Requests-g@

    affaire à suivre...

Discussions similaires

  1. [AJAX] configurer requete ajax
    Par knebhi dans le forum AJAX
    Réponses: 1
    Dernier message: 20/08/2009, 11h53
  2. Réponses: 1
    Dernier message: 17/04/2008, 15h57
  3. [AJAX] [IE] Requete Ajax en cours et changement de page
    Par ..:: Atchoum ::.. dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 17/10/2007, 12h30
  4. [AJAX] Temporisation requete AJAX
    Par cerede2000 dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 07/06/2007, 10h00
  5. [AJAX] deux requetes ajax dans une même page
    Par mitmit dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 02/05/2007, 12h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo