Rolf B: XMLHttpRequest von anderer IP

Beitrag lesen

Hallo Dennis2019,

wenn ich mir dein JS so anschaue, hast Du mehrere Probleme. Eins ist das Absetzen des XMLHttpRequests. Da schreibst Du:

request.open("GET", "http://192.168.178.104", "ajax_inputs" + strLED1 + strLED2 + strLED3 + strLED4 + nocache, true);

Das ist in vielerlei Hinsicht ungeschickt bzw. falsch.

  1. Die Query-Parameter musst Du per Stringverkettung an die Host-Adresse (also http://192.168.178.104) anhängen. Der dritte Parameter von open() heißt async (guck ins Wiki) und steuert, ob der Ajax-Aufruf synchron oder asynchron laufen soll. Lass ihn weg. Der default ist false (asynchron), und das ist richtig.

  2. Du befüllst strLED1 bis strLED4 nicht nur mit den Parametern, sondern mit einer vollständigen URL. Das führt zu Unsinn, wenn Du eine Gesamt-URL zusammensetzen willst. Es ist aber gar nicht nötig, diese Variablen zu benutzen.

  3. Es ist Unsinn, als Reaktion auf Checkbox-Änderungen oder Button-Klicks sofort die URL-Parameter zu ändern. Damit vermischst Du Datenmodell und Arduino-Interface. Deine Checkboxen haben bereits einen internen State. Und für deine Buttons hat Du State-Variablen. Das reicht. Die Parameter für den Ajax-Request baust Du genau dann zusammen, wenn der Ajax-Call gemacht wird. Und den nocache-Parameter brauchst Du nicht, wenn Du es mittels des entsprechenden HTTP-Headers richtig machst. Besser noch ist es, auf dem Arduino diesen Header in die Response zu setzen, dann cached der Browser gar nicht erst.

   let url = "http://192.168.178.104"
           + "?LED1=" + (LED_form.LED1.checked ? "1" : "0")
           + "&LED2=" + (LED_form.LED2.checked ? "1" : "0")
           + "&LED3=" + (LED3_state ? "1" : "0")
           + "&LED4=" + (LED4_state ? "1" : "0");
   
   request.open("GET", url);
   request.setRequestHeader("Cache-Control", "no-cache");
   request.send();

Nix mehr mit strLED1 bis strLED4. Die Funktion GetCheck entfällt. Der click-Eventhandler auf den Checkboxen entfällt. Das ist auch gut so, weil click eigentlich falsch ist - richtig wäre das change Event. Du hast Glück, dass der Browser etwas zur Rettung von Leuten ohne Maus tut und auch bei Tastaturbedienung das click-Event auslöst.

Und wenn Du LED3_state und LED4_state mit false statt 0 initialisierst, reduziert sich der click-Handler der Buttons 3 und 4 zunächst einmal auf

   ClickButton3() {
      LED3_state = !LED3_state;
   }
   ClickButton4() {
      LED4_state = !LED4_state;
   }

aber das reicht noch nicht, weil Du ja noch ein optisches Feedback einbauen musst, ob die LED an oder aus ist. Checkbox ist einfacher...

Ach so, Checkbox. Das hier ist übrigens auch falsch:

<input type="checkbox" name="LED1" value="0" onclick="GetCheck()" />LED 1 (D6)<br /><br />

Richtig ist:

<label><input type="checkbox" name="LED1" value="0"  /> LED 1 (D6)</label>

und etwas CSS, das dem Label die Eigenschaften display: block; und margin-bottom: 1em; gibt. Vorteil: Du kannst auch auf den Text klicken um die Checkbox umzuschalten, so wie es ein GUI-verwöhnter User erwartet. Die <br> sind präsentationsbezogenes Markup und sollten vermieden werden. <br> reicht übrigens, <br /> brauchst Du nur bei XHTML.

Soooo. Nachdem wir nun einiges am Client gemacht haben, stellt sich die Frage nach dem Verbleib der Antwort. PL hat bereits CORS angesprochen: Cross Origin Resource Sharing. Dein Arduino erlaubt nicht, dass seine Ressourcen von einer Seite genutzt werden, die nicht vom Arduino geladen wurde. Probiere doch zuerstmal, aus GET ein POST zu machen. Aus mehreren Gründen. Zum einen liest Du nicht nur, sondern änderst was, nämlich die LEDs. Zum zweiten werden POST Requeste nicht gecached, d.h. die Akrobatik mit Cache-Control könnte entfallen. Und drittens ist CORS nur bei Lesezugriffen sensibel, bei Schreibzugriffen weniger. Ich habe hier kein Testsystem dafür und weiß nicht, ob das reicht. Ansonsten guck mal in die MDN: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS.

Rolf

--
sumpsi - posui - clusi