Visualizzazione del caricamento del testo durante l'esecuzione di una richiesta Web

StackOverflow https://stackoverflow.com/questions/185239

  •  06-07-2019
  •  | 
  •  

Domanda

Ho un pulsante sul mio modulo web. Facendo clic su questo pulsante, verrà eseguito un HttpWebRequest durante il gestore eventi onclick. Dopo la richiesta copiamo la risposta dalla richiesta in HttpContext.Current.Response e la inviamo al client.

Questa richiesta Web può richiedere del tempo (fino a 5 secondi, poiché sta generando un rapporto). Durante questo periodo l'utente non ha alcuna indicazione che qualcosa stia succedendo, ad eccezione della barra di avanzamento del browser e dell'icona IE in rotazione (se stanno utilizzando IE). Quindi ho bisogno di un indicatore di caricamento mentre questo accade.

Ho provato a usare javascript che si attiva durante l'evento onclick del pulsante (usando OnClientClick) e mentre funziona, non so come scoprire quando la richiesta web è terminata. Poiché abbiamo appena inviato la risposta al client, non si verifica un postback completo.

Ho provato a racchiudere il pulsante in un UpdatePanel e ad utilizzare UpdateProgress, ma quando inviamo la risposta a HttpContext.Current.Response e chiamiamo Response.End (), otteniamo un errore nel javascript, poiché la risposta non è ben formato (stiamo restituendo un foglio Excel da scaricare per l'utente).

Dato che stiamo inviando indietro un file che gli utenti possono scaricare, non voglio far apparire una finestra separata, da allora in IE otterrebbero la barra delle informazioni che blocca il download.

Qualche idea qui?

È stato utile?

Soluzione

In alternativa alla libreria Professional AJAX.NET, jQuery ha un modo davvero carino di farlo.

Dai un'occhiata a questo esempio dell'uso di un PageMethod .NET (se possibile nel tuo scenario).

Definisci una chiamata del metodo di pagina in jQuery, puoi virare sul tuo messaggio di caricamento ... in un div nascosto.

Pronuncia il callback che desideri restituire in caso di successo (ovvero quando viene generato il rapporto di 5 secondi) quindi nascondere il caricamento e gestire i dati.

Dai un'occhiata al javascript sulla mia pagina dei contatti per un esempio (vedi la fonte).

  1. Ho un pulsante nella pagina, aggiungi jQuery onClick.
  2. Quando si fa clic che mostra un div di caricamento nascosto, effettua una chiamata ajax a un metodo di pagina che accetta i parametri del modulo.
  3. Il metodo della pagina invia email ecc., quindi torna al modulo nel metodo javascript onSuccess che ho lì.
  4. onSuccess nasconde il div di caricamento.

Altri suggerimenti

Un semplice trucco che ho usato in passato è il reindirizzamento a una pagina intermedia con una barra di avanzamento animata (gif) e quindi fare in modo che quella pagina faccia il post REALE dei dati. (o persino pop-up di un livello con l'animazione su di esso e un messaggio educato che chiede all'utente di attendere un minuto o due)

Il semplice feedback della gif animata crea l'illusione per l'utente finale che l'app non è bloccata e saranno più pazienti.

Un altro approccio è quello di consegnare i dati a un thread di lavoro e restituirli immediatamente con un messaggio che indica che il report verrà inviato via e-mail o reso disponibile nel " reports " sezione del sito quando è pronta. Questo approccio è privo del vantaggio della notifica istantanea al completamento del report.

Ecco la mia soluzione:

  1. Scarica ed esamina gli esempi della libreria AJAX.NET professionale gratuita.
  2. Scrivi un AjaxMethod che crea il tuo file e restituisce la posizione del file come parametro.
  3. Scrivi la tua funzione lato client per chiamare il metodo al passaggio 2. Quando questo metodo viene chiamato mostra un indicatore.
  4. Scrivi un metodo di richiamata sul lato client per nascondere l'indicatore e mostrare / scaricare il file richiesto dall'utente.
  5. Aggiungi la tua funzione lato client chiama il tuo elemento pulsante.

Al termine del metodo sul lato server verrà chiamato il callback.

Spero che questo aiuti!

La soluzione che sto presentando qui ha lo scopo di mostrare un metodo per lasciare un " Loading ... " casella da visualizzare durante l'elaborazione lato server e scompare al termine dell'elaborazione lato server.

Lo farò con i macchinari AJAX di base (testati su FF, ma IE dovrebbe anche essere ok), cioè non usando un framework come Prototype o jQuery o Dojo, poiché non hai specificato le tue conoscenze al riguardo.

Per farti capire meglio il trucco, il seguente è solo un piccolo esempio e non finge di essere una soluzione pronta all'uso. Tendo a non essere superficiale, ma penso che un esempio più chiaro possa spiegare meglio di molte parole.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>First Example</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <style>
            .hidden {
                display: none;
            }
            .loadingInProgress {
                color: #FFFFFF;
                width: 75px;
                background-color: #FF0000;
            }
        </style>
    <script type="text/javascript">
        var httpRequest;
        if (window.XMLHttpRequest) { // Mozilla, Safari, ...
            httpRequest = new XMLHttpRequest();
            httpRequest.overrideMimeType('text/xml');
        } else if (window.ActiveXObject) { // IE
            try {
                httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
            }
            catch (e) {
                try {
                    httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
                }
                catch (e) {}
            }
        }

        if (!httpRequest) {
            alert('Giving up :( Cannot create an XMLHTTP instance');
        }

        httpRequest.onreadystatechange = function(){
            switch (httpRequest.readyState) {
            case 1: // Loading
                document.getElementById('loading').className = "loadingInProgress";
                break;
            case 4: // Complete
                document.getElementById('loading').className = "hidden";
                if (httpRequest.status == 200) {
                    // perfect!
                } else {
                    // there was a problem with the request,
                    // for example the response may be a 404 (Not Found)
                    // or 500 (Internal Server Error) response codes
                }
                break;
            }
        };

        function go() {
            httpRequest.open('GET', document.getElementById('form1').action, true);
            httpRequest.send('');
        }
    </script>

  </head>
  <body>
      <div id="loading" class="hidden">Loading...</div>
      <form id="form1" name="form1" action="doSomething.php">
          <input type="button" value="Click to submit:" onclick="go()" />
      </form>
  </body>
</html>

Come puoi vedere, c'è un <div> che contiene il " Loading ... " messaggio.

Il principio è mostrare / nascondere il XMLHttpRequest in base al readyState oggetto onreadystatechange.

Ho usato il gestore action di Cache-control: no-cache per attivare la <=> modifica.

Lo script php back-end che uso (dichiarato come il modulo <=>) fa solo uno sleep (5), per lasciare " Loading ... " il messaggio appare per 5 secondi.

<?php
sleep(5);
header('Cache-Control: no-cache');
echo "OK";
?>

L'intestazione <=> è necessaria, poiché di solito se non la imposti, il browser memorizzerà nella cache la risposta evitando di reinviare la richiesta se necessario.

Una buona fonte per " per iniziare " La documentazione AJAX è Mozilla MDC .

Il tutto potrebbe essere gestito in modo molto più delicato da un framework Javascript come Prototype, sfruttando il suo approccio sicuro per i browser, risparmiando ore di debug.


Modifica:

Ho scelto php perché non conosco ASP.NET né ASP, mi dispiace per quello.


Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top