none
IE Fenster schließen während asynchroner ADO noch aktiv ist RRS feed

  • Frage

  • Es handelt sich hierbei um eine alte Classic asp Anwendung mit VBScript und JScript, in der teilweise direkt vom Client aus auf den SQL Server per ADO zugegriffen wird. Bisher wurde der IE 8 verwendet und nun soll alles derart überarbeitet werden, dass mit dem IE 11 gearbeitet werden kann.

    Problem:

    Wenn in einem Sub-Fenster über ADO asynchron auf ein SQL Server zugegriffen wird und der Benutzer dann dieses Fenster schließt bevor der Zugriff abgeschlossen ist, dann wird das Sub-Fenster und auch das Hauptfenster geschlossen und damit die ganze Anwendung abgebrochen.

    Während des asynchronen Zugriffs werden die Ereignisse onunload bzw onbeforunload ab IE9 nicht ausgelöst, ein abort auf dem ADO Objekt kann daher nicht ausgelöst werden. Gibt es hierzu alternative Vorgehensweisen? Z.B. schließen des Fensters solange verhindern bis asynchroner Zugriff abgearbeitet worden ist.

    Ein synchroner Zugriff ist aufgrund der zum teil längeren Ladezeiten keine Alternative.



    Mittwoch, 9. April 2014 07:05

Alle Antworten

  • Hallo Mike,

    aus verschiedenen Gründen würde ich diese Vorgehensweise weder empfehlen noch beibehalten.

    Es wäre sinnvoller, bspw. über jQuery.ajax ein ASP Script auf dem Server anzusprechen, welches die Abfrage durchführt und das Ergebnis dann im JSON oder XML Format an den Client liefert (theoretisch kann man auch den HTML Code für das Ergebnis gleich aufbereiten, ob das aber nun Sinn macht, musst Du selbst entscheiden).

    Letztendlich wirst Du bei der bisherigen Variante immer von Änderungen im Browser selbst abhängig sein. Wenn wie hier bestimmte Events in bestimmten Konstellationen nicht mehr ausgelöst werden, hast Du keine Möglichkeit einzugreifen.

    Wenn onunload und onbeforeunload nicht mehr ausgelöst werden, kannst Du in den Prozess des Schließens des Formulars auch nicht mehr eingreifen.

    Die einzige Option, die mir dazu noch einfällt, wäre, den Browser per X-UA-Compatible Meta Tag anzuweisen, dass als Modus IE8 verwendet werden soll. Siehe dazu:

      http://blogs.technet.com/b/iede/archive/2013/12/02/ie8-compatibility-view-wie-kann-manuell-serverbasiert-oder-per-policy-das-verhalten-beeinflusst-werden.aspx


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Mittwoch, 9. April 2014 17:51
  • Hallo Ionut,

    das mit dem Beispiel Code ist nicht ganz einfach, da die Anwendung recht viele Includes verwendet. Ich habe eine Testseite eingefügt, mit der wir das Problem reproduzieren können. Du siehst hier auch auskommentierte Versuche in den Events den asynchronen Aufruf abzubrechen, aber das Event wird wärend des asynchronen Aufrufs nicht ausgelöst.

    Soweit ich recherchieren konnte, wurde bis zum IE8 ein asynchroner Aufruf automatisch gestoppt, so dass nicht eine Rückmeldung ins Leere laufen konnte.

    Ich bin mir bewußt, dass die Architektur nicht optimal ist, aber so sieht diese Anwendung nun mal aus und kann nicht eben mal schnell geändert werden.

    Ziel ist erstmal auf IE11 zu kommen und da ist das ein Problem zu dem wir bisher keine Lösung haben. Wir nutzten übrigens den Kompatibilitätsmodus, das hilft hierbei aber nicht weiter.

    Danke und Gruß

    Michael

    <!DOCTYPE html>
        <head>
    	<META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=ISO-8859-1">
      	<meta http-equiv="X-UA-Compatible" content="IE=10,9,8">
    	<title>hgoSQL-Text</title>
    	<script type="text/javascript" src="../JSDIR/sqlConnString.js"></script>
    	<script type="text/javascript" src="../ol/hgoSQL.js"></script>
    	<script type="text/javascript" src="../JSDIR/hgoGlobal.js"></script>
    	<script type="text/javascript">
    		window.onerror=myError;
    		var s = "Wenn das Fenster zu schnell geschlossen wird, dann kann es passieren, dass die ganze Session weg ist."
    			s+= "\nWenn du das wirklich riskieren willst, dann kannst du die Seite verlassen."
    		function myError(Nachricht,Datei,Zeile) {
    			alert("Fehler:\n\nMeldung: " + Nachricht + "\nQuelle: " + Datei + "\nZeile: " + Zeile)
    			return true;
    		}
    		function checkEnde() {
    			// If there things still loading, then fake the unload event
    			if (document.readyState == 'interactive') {
    			    function stop() {
    						// Prevent memory leak
    						document.detachEvent('onstop', stop);
    						// Call unload handler
    						checkEnde2();
    			    };
    			    // Fire unload when the currently loading page is stopped
    			    document.attachEvent('onstop', stop);
    				// Remove onstop listener after a while to prevent the unload function
    				// to execute if the user presses cancel in an onbeforeunload
    				// confirm dialog and then presses the stop button in the browser
    				window.setTimeout(function() {
    					document.detachEvent('onstop', stop);
    				}, 0);
    			}
    			// if xmlHttpRequest has been called it has to be aborted before windows can be closed (event: onbeforeunload)
    /* 			if (hgoSQL.XML){
    				hgoSQL.XML.abort();
    				}
    				debugger;
    				alert('Leaving ...') */
    		}
    
    		function checkEnde2() {
    			alert('Unload event occured.');
    		}
    
    	    var t
    	    function afterLoad() {
    		var d = document.getElementById('infoid');
    		d.innerHTML = 'documentMode='+document.documentMode + '<br>CompatMode='+document.compatMode
    		t = document.getElementById('divid').firstChild;
    	    }
    
    	    function doRun(waitSecs, mode, param) {
    			t.nodeValue = 'läuft'
    			hgoSQL.init()
    			hgoSQLWait()
    			window.setTimeout(function() { doWait(waitSecs,mode,param); }, 1)
    	    }
    
    	    function doWait(waitSecs,mode,param) {
    			var stmt = "execute dbo.Wait "+waitSecs+", 1, 0";
    			var text
    			switch (mode) {
    			    case 0:
    			    			hgoSQLExec(stmt);
    							text = 'Exec fertig'
    							break;
    		    	case 1:
    							text = 'Fetch:'+ hgoSQLFetch(stmt);
    							break;
    		    	case 2:
    							if (typeof(param) == 'boolean') {
    			    				var rs = new recordSet({useIIS:param});
    							} else {
    							    var rs = new recordSet();
    							}
    							rs.Open(stmt,hgoSQL.conn)
    							text = 'nach Open()'
    							break;
    			}
    		//rs.Close();
    			t.nodeValue = 'fertig'
    	    }
    
    	    window.attachEvent('onunload', checkEnde2);
    	    window.attachEvent('onbeforeunload', checkEnde)
    	</script>
        </head>
        <body onLoad="afterLoad()">
    	<h3>hgoSQL-Crash</h3>
    	<h4>Anleitung:</h4>
    	<ul><li>den roten Button mit (useIIS:false) klicken</li>
    	    <li>innerhalb von 8 Sekunden das Fenster schließen</li>
    	</ul>
    	Falls erfolgreich, werden dadurch alle IE-Fenster geschlossen!<br>
    	Grund ungekannt, Hypothese:<br>
    	der hgoSQL-Request ist noch unterwegs<br>
    	und in diesem Zustand ist das Schließen dieses Fensters der Auslöser<br>
    	für das Schließen aller zugehörigen Fenster.<br>
    	<br>
    	    <!-- weitere Tests
    	    <button onClick="doRun(10,0);">Klick mich (hgoSQLExec)</button>
    	    <button onClick="doRun(10,1);">Klick mich (hgoSQLFetch)</button>
    	    <button onClick="doRun(10,2);">Klick mich (new RecordSet()</button>
    	    -->
    	    <button onClick="doRun(10,2,true);">Klick mich (new RecordSet({useIIS:true})</button>
    	    <button onClick="doRun(10,2,false);" style=color:red>Klick mich (new RecordSet({useIIS:false})</button>
    	<div id=divid>&nbsp;</div>
    	<div id=infoid></div>
        </body>
    </html>
    

    Mittwoch, 16. April 2014 10:31