2016-08-12 4 views
1

Ich war nicht verantwortlich für die Apache-Konfiguration, daher bin ich mir nicht sicher, was ich in Bezug auf nützliche conf-Text bieten kann, aber ich bin ziemlich sicher, dass ich habe verengt das Problem bis zum Login. EventSource funktioniert sowohl lokal auf XAMPP ohne Login als auch nach der Aktualisierung der Seite nach der Authentifizierung auf dem Produktionsserver einwandfrei, aber beim erstmaligen Laden auf dem Server wird keine Verbindung geöffnet. Hat jemand dieses Problem schon einmal gesehen? Ich konnte nicht irgendetwas im Internet darüber nach dem Suchen nach den letzten paar Tagen finden.JavaScript EventSource wird keine Verbindung nach Apache basic auth öffnen

Edit: Einige Code

Einige der serverseitigen Code (die meist nicht relevant sein sollte):

header('Content-Type: text/event-stream'); 
header('Cache-Control: no-cache'); 

$client_stream = new RedisStream(); 
$client_stream->poll(1); //The loop, with sleep time as a parameter 

Das JavaScript:

var xhttpViewSet; 
var xhttpSearch; 
var view = 'tile'; 
var search = ''; 

var seed_url = '/core/seed_view.php'; 
var stream_url = '/core/stream.php'; 

var default_class = 'panel-default'; 
var success_class = 'panel-success'; 
var warning_class = 'panel-warning'; 
var danger_class = 'panel-danger'; 

function UpdateClient(c_name, c_obj) { 
    if ((c_element = document.getElementById(c_name)) !== null) { 
     c_element.classList.remove('text-muted'); 

     c_element.classList.remove(default_class); 
     c_element.classList.remove(success_class); 
     c_element.classList.remove(warning_class); 
     c_element.classList.remove(danger_class); 

     switch (c_obj['status']) { 
      case 0: 
       c_obj['status'] = 'OK'; 
       c_element.classList.add(success_class) 
       break; 
      case 1: 
       c_obj['status'] = 'Warning'; 
       c_element.classList.add(warning_class) 
       break; 
      case 2: 
       c_obj['status'] = 'Critical'; 
       c_element.classList.add(danger_class) 
       break; 
      default: 
       c_obj['status'] = 'Unknown'; 
       c_element.classList.add(danger_class) 
       break; 
     } 

     for (i in c_obj) { 
      var var_nodes = c_element.getElementsByClassName(i); 
      if (var_nodes.length > 0) { 
       for (var j = var_nodes.length - 1; j >= 0; j--) { 
        var_nodes[j].innerHTML = c_obj[i]; 
       } 
      } 
     } 
    } 
} 

function SetView() { 
    var view_url = seed_url + '?search=' + search + '&view=' + view; 

    xhttpViewSet.open('GET', view_url, true); 
    xhttpViewSet.send(); 
} 

var main = function() { 
    container = document.getElementById('content'); 

    if (new XMLHttpRequest()) { 
     xhttpViewSet = new XMLHttpRequest(); 
     xhttpSearch = new XMLHttpRequest(); 
    } else { 
     xhttpViewSet = new ActiveXObject('Microsoft.XMLHTTP'); 
     xhttpSearch = new ActiveXObject('Microsoft.XMLHTTP'); 
    } 

    var stream = new EventSource(stream_url); 
    stream.onopen = function() { 
     console.log('Connection opened.'); //This doesn't fire 
    } 

    stream.onmessage = function(e) { 
     var c_obj = JSON.parse(e.data); 
     UpdateClient(c_obj.name, c_obj.value); 
    }; 

    xhttpViewSet.onreadystatechange = function() { 
     if (xhttpViewSet.readyState == 4) { 
      var resp = xhttpViewSet.responseText; 
      if (xhttpViewSet.status == 200 && resp.length > 0) { 
       container.innerHTML = resp; 
       if (view == 'list') { 
        $('#computer-table').DataTable({ 
         "lengthMenu": [[25, 50, 100], [25, 50, 100]] 
        }); 
       } 
      } else { 
       container.innerHTML = '<error>No computers matched your search or an error occured.</error>'; 
      } 
     } 
    } 
    SetView(); //This successfully does all but make the EventSource connection, and only fails to do that on first load 

    document.getElementById('list-view').addEventListener('click', function() { 
     view = 'list'; 
     SetView(); 
    }); 

    document.getElementById('tile-view').addEventListener('click', function() { 
     view = 'tile'; 
     SetView(); 
    }); 

    document.getElementById('search').addEventListener('keyup', function() { 
     search = this.value.toUpperCase(); 
     SetView(); 
    }); 

    document.getElementById('clear-search').addEventListener('click', function() { 
     document.getElementById('search').value = ''; 
     search = ''; 
     SetView(); 
    }); 
}; 

window.onload = main; 
+0

Sie werden einige weitere Details benötigen. z.B. Client-Code, Server-Code, die URLs, die Sie verwenden ... etwas, um weiterzugehen. Eigentlich noch wichtiger: Was passiert in der Konsole? Testen Sie mit den Entwicklertools in mindestens zwei Browsern. Achte darauf, welche Weiterleitungen passieren, welche Header gesendet werden usw. –

+0

@DarrenCook Ich werde updaten, um den Front- und Back-End-Code hinzuzufügen, aber was passiert in der Konsole: nichts Interessantes im Moment. Für einfaches Debugging und Verbindungszählen habe ich "Verbindung geöffnet" protokolliert.", und das wird nicht sofort nach dem Einloggen angezeigt, also ich vermute, es ist entweder das" onopen ", das nicht funktioniert oder die Erstellung des EventSource-Objekts selbst; es war - und sollte immer noch - so funktionieren wie es ist. –

+0

Do you PHP - Sitzungen verwenden Anders als beim Login unterscheidet sich das Produktivsystem von dem lokalen XAMPP - System, wo es funktioniert Was "nichts Interessantes" in der Debug - Konsole angeht, sind alle möglichen Ergebnisse interessant: ZB sehen Sie entweder Auth-Header gesendet wird, die Ihnen eine Sache erzählt, oder Sie sehen es nicht, die Ihnen eine andere Sache erzählt :-) –

Antwort

1

Es ist ein bisschen schwer zu wissen, ohne viel mehr Informationen, aber basierend auf was Sie bisher gesagt haben, denke ich, es ist eines der:

HEAD/OPTIONS: Einige Browser senden einen HEAD- oder OPTIONS-HTTP-Aufruf an ein Serverskript, bevor sie den GET- oder POST-Befehl senden. Der Zweck des Sendens von OPTIONS besteht darin zu fragen, welche Header gesendet werden dürfen. Es ist möglich, dass dies als Teil des Login-Prozesses passiert; dass könnte erklären, warum es funktioniert, wenn Sie neu laden. Weitere Informationen finden Sie in Kapitel 9 von Data Push Apps mit HTML5 SSE (Disclaimer: mein Buch). Im Grunde müssen Sie an der Spitze Ihres SSE-Skripts den Wert $_SERVER["REQUEST_METHOD"] überprüfen, und wenn es "OPTIONS" ist, abfangen und sagen, welche Header Sie akzeptieren möchten.

header("Access-Control-Allow-Headers: Last-Event-ID,". 
    " Origin, X-Requested-With, Content-Type, Accept,". 
    " Authorization");` 

CORS: Ich habe diese ein, bevor sie verwendet Die HTML-Seiten-URL und die SSE-URL müssen identisch Ursprung haben. Es gibt detaillierte Erklärungen (spezifisch für SSE) in Kapitel 9 von Data Push Apps mit HTML5 SSE (nochmal) oder (weniger spezifisch) unter Wikipedia. Wenn dies das Problem ist, fügen Sie Ihrem SSE-Skript header("Access-Control-Allow-Origin: *"); hinzu.

withCredentials: Es gibt einen zweiten Parameter an die SSE-Konstruktor, und verwenden Sie es wie folgt aus: var stream = new EventSource(stream_url, { withCredentials: true }); Es sagt, es ist okay, die Auth-Anmeldeinformationen zu senden. (Noch einmal, Kapitel 9 des Buches geht ausführlicher - Entschuldigung für die wiederholten Stecker!) Es gibt einen zweiten Schritt, auf der Serverseite: oben im PHP SSE-Skript müssen Sie Folgendes hinzufügen.

header("Access-Control-Allow-Origin: "[email protected]$_SERVER["HTTP_ORIGIN"]); 
header("Access-Control-Allow-Credentials: true"); 

PHP Sessions Sperren: Dies verursacht normalerweise das entgegengesetzte Problem, das ist, dass der SSE-Skript, um die PHP-Sitzung gesperrt ist, so dass keine andere PHP-Skripten arbeiten. Siehe https://stackoverflow.com/a/30878764/841830 für den Umgang damit. (Es ist eine gute Idee, dies trotzdem zu tun, auch wenn es nicht Ihr Problem ist.)

+0

Interessant; Ich werde einige davon versuchen und zu dir zurückkommen. Jetzt, wo du es gesagt hast, denke ich, dass es wahrscheinlich Header-bezogen ist, aber ich werde es nicht sicher für mindestens ein paar Tage wissen, also werde ich die Antwort noch nicht akzeptieren - obwohl ich werde, wenn ich kann. –