Forum: PC-Programmierung Wie dynamische Webseite aufbauen?


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von M. M. (maik3)


Lesenswert?

Moinsen,

ich komme ja aus der embedded-Ecke, probiere mich aber trotzdem gerne 
mal an anderen Themen.

Folgende Situation habe ich grad:
Ich habe ein Python-Skript verbrochen welches sich aus verschiedenen 
Quellen diverse Daten abholt und diese sammelt. Das Skript läuft dabei 
dauerhaft als daemon.

Nun möchte ich per Flask dem Skript ein Webinterface anflanschen, bzw. 
das läuft bereits. Mein Skript ist in der Lage, eine html-Seite 
auszuliefern. In diesem  Webinterface sollen die angesammelten Daten 
visualisiert werden. Zu Beginn würde ich das erstmal in eine simple 
html-Tabelle packen.

Nun stellt sich mir aber die Frage wie ich die Webseite regelmäßig 
aktualisiere.
Nicht nur dass sich die Daten im Laufe der Zeit ändern, es können auch 
Einträge dazu kommen (sprich: die Tabelle kriegt mehr Zeilen und 
Spalten).

Ich könnte jetzt den html-Code der Seite bereits serverseitig, also im 
Pythonskript, mit den Daten befüllen. Der Browser würde dann nur eine 
simple, statische Seite geliefert bekommen.

Methode 2 wäre, ein paar Javaskripte in die Seite einzubetten. Per 
REST-Api könnte die Seite dann die dynamischen Inhalte nachladen (als 
JSON-Struktur) und dann per jquery die Seite laufend aktualisieren.

Methode 1 wäre simpler, hat aber den Nachteil dass der Server nicht nur 
Daten ausliefert sondern sich auch um so Details wie die graphische 
Aufbereitung derselbigen kümmern muss.
Methode 2 ist etwas aufwendiger, dafür sind Datenschnittstelle und die 
Anzeige der Daten sauber getrennt. Es wären sogar verschiedene 
Visualisierungen denkbar.

Ich brauch ein paar Denkanstöße.
Wie würdet ihr das lösen?

von Franko S. (frank_s866)


Lesenswert?

M. M. schrieb:
> Wie würdet ihr das lösen?
Kommt drauf an.

von Alex Z. (alexander_z49)


Lesenswert?

Die Lösung heißt WebSocket, kannst du in deinem Flask auch einbauen. 
Wenn ein Client deine Seite aufruft, wird zusätzlich eine WS Verbindung 
aufgebaut. Immer wenn du neue Daten Hast, kannst du diese als Broadcast 
an deine Clients sicken und dann auf Clientseite mit JavaScript 
auswerten.

von Monk (roehrmond)


Lesenswert?

M. M. schrieb:
> Nun stellt sich mir aber die Frage wie ich die Webseite regelmäßig
> aktualisiere.

Eine gängige Methode ist AJAX.

Du kannst allen dynamischen Elementen eine eindeutige ID geben. Ein 
Javascript ruft dann zyklisch Updates vom Server ab. In jedem Update 
benennt der Server die des zu ändernden Elementes, sowie dessen Inhalt.

Tipp: Du kannst das Javascript so schreiben, dass es den Server in einer 
Endlosschleife abfragt. Der Server muss nicht unbedingt sofort 
antworten, sondern kann den Browser ruhig warten lassen, bis wirklich 
neue Daten vorliegen. Das reduziert die CPU Auslastung und Stromaufnahme 
beim Browser.

Ob deine Updates im HTML Format sind (also server-seitig aufbereitet) 
oder im JSON Format (also browser-seitig aufbereitet) ist dann 
hauptsächlich eine Geschmacksfrage. Kommt drauf an, auf welcher Seite du 
lieber den dazu nötigen Strom verbrauchen willst.

: Bearbeitet durch User
von Max M. (jens2001)


Lesenswert?

Weist du denn welchen Browser der Client benutzt und ob JS nicht evtl. 
deaktviert ist?
Statisches HTML ist immer der kleinste gemeinsame Nenner.

von Michael B. (laberkopp)


Lesenswert?

M. M. schrieb:
> Wie würdet ihr das lösen?

Ja, es gibt viele Wege.

Eine einfache HTML Seite (mit Auto-Refresh) kann nicht nur jeder Browser 
anzeigen, man kann sie auch einfach (z.B. per Python) auf Empfängerseite 
auseinandernehmen und ihren Inhalt analysieren.

Man könnte sie auch in PDF verwandeln und auf eBookReadern anzeigen.

Den Zugriff verbaust du dir mit komplexen Skriptingseiten.

Eine einfache Skripting-Seite holt sich den Rahmen, der erhalten bleibt, 
und updated durch ihren Skrip nur die enthaltene Tabelle. Der Skript 
braucht nur die Daten zu übertragen, und hält die Füsse still wenn sich 
nichts verändert hat damit es nicht flackert.

von Monk (roehrmond)


Lesenswert?

Wer in seinem Browser Javascript deaktiviert, ist selber Schuld bzw. 
kann das selber umstellen. Ich denke, man muss für diese Leute keine 
Sonderlocke mehr vorsehen, das ist nicht mehr zeitgemäß.

Hier ein altes Beispiel, mit dem ich die "Navigationsleiste" auf meiner 
Hompepage nachlade:
1
<html>
2
  <body>
3
    <div id="navi"></div>
4
5
    <script type="text/javascript">
6
      ajax_load("navi", "navigation.html");
7
    </script>
8
9
    Hier kommt der eigentliche statische Inhalt der Seite
10
11
  </body>
12
</html>
1
function ajax_load(id,url) {
2
  try {
3
    var request = new XMLHttpRequest();
4
    request.open("GET", url, true);
5
6
    request.onreadystatechange = function () {
7
      if (request.readyState == 4) {
8
         document.getElementById(id).innerHTML = request.responseText;
9
      }
10
    };
11
    
12
    request.send();
13
  }
14
  catch (e) {
15
    console.error(e, e.stack);
16
  }
17
}

Dieses Beispiel kommt ohne Endlosschleife aus, weil die Navigation nur 
einmal geladen werden muss. Aber ich denke, du kannst trotzdem davon 
abgucken. Ich wollte damit nur zeigen, dass AJAX ganz einfach ist.

: Bearbeitet durch User
von Εrnst B. (ernst)


Lesenswert?

Steve van de Grens schrieb:
> Eine gängige Methode ist AJAX.

"AJAX" ist ein Buzzword aus den 1990ern und 2000ern. Auch wenn das 
Grundkonzept in etwa gleichgeblieben ist, sollte man das heute nicht 
mehr so nennen.
Dazu ist die Abkürzung zu stark mit den damals üblichen&nötigen 
Flash-Player-Active-X-XMLHttpRequest-würgarounds verknüpft.
Wenn man nach "AJAX" sucht, wird man von veraltetem JS-Code erschlagen, 
üblicherweise mit XMLHttpRequest & Callback-Hölle, obwohl heute die 
Browser alle "echtes" asynchrones Javascript (async/await) unterstützen 
würden...

Steve van de Grens schrieb:
> Der Server muss nicht unbedingt sofort
> antworten, sondern kann den Browser ruhig warten lassen, bis wirklich
> neue Daten vorliegen.

das sogenannte "longpolling" ist ähnlich alt, inzwischen als 
ServerSentEvents aber formalisiert und mit einfacher API im Browser zu 
handhaben.

https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events

Oder gleich Websockets...

Ja, die ganzen Webtechniken aus den 1990ern funktionieren auch heute 
noch. Aber wenn jemand was Neues entwickeln will, kann er auch aktuelle 
Techniken einsetzen.
Muss ja nicht gleich eine React-Webapp werden.

von Εrnst B. (ernst)


Lesenswert?

Steve van de Grens schrieb:
> Ich wollte damit nur zeigen, dass AJAX ganz einfach ist.

Steve van de Grens schrieb:
> function ajax_load(id,url) {

Achtung: Dein try-catch ist unvollständig. Exceptions, die aus dem 
onreadystatechange-Handler geworfen werden, fängt das catch nicht.

um dein Beispiel zu aktualisieren:
1
async function aj_load(id,url) {
2
  try {
3
   document.getElementById(id).innerHTML = await (await fetch(url)).text();
4
  } catch (e) {...}
5
}

von Kolja L. (kolja82)


Lesenswert?

Zunächst AJAX und jQuery sind out 🫣

Ob dir der Server statische HTML seiten generiert oder du die Daten 
mittels JavaScript nachlädst, ist erstmal egal.

Meine Kriterien wären UX, DX und SEO.

UX - User experience
Werden die Daten via JavaScript geladen ist das navigieren, sortieren 
oder filtern meist flüssiger als bei auf dem server generierten seiten.

DX - Developer experience
Was entspricht ehr deinen Fähigkeiten?
Eine brauchbare Lösung gut umgesetzt ist meist besser, als die beste 
Lösung stümperhaft programmiert.


SEO - Search engine optimization
Wenn der Inhalt von Suchmaschinen leicht indiziert werden soll, sind 
statische bzw servergenerierte Seiten besser, da der Bot kein JS 
ausführen muss um an den Inhalt zu kommen.

Die eierlegenden Wollmilchsau:

Der Server liefert bei der ersten Anfrage statischen Inhalt und 
aktualisiert diesen bei Bedarf dynamisch.

Eine Bibliothek, die das recht simple umsetzt ist: HTMX
Dann muss die REST API aber HTML liefern und kein JSON.

von Ein T. (ein_typ)


Lesenswert?

M. M. schrieb:
> Folgende Situation habe ich grad:
> Ich habe ein Python-Skript verbrochen welches sich aus verschiedenen
> Quellen diverse Daten abholt und diese sammelt. Das Skript läuft dabei
> dauerhaft als daemon.
>
> Nun möchte ich per Flask dem Skript ein Webinterface anflanschen, bzw.
> das läuft bereits. Mein Skript ist in der Lage, eine html-Seite
> auszuliefern. In diesem  Webinterface sollen die angesammelten Daten
> visualisiert werden. Zu Beginn würde ich das erstmal in eine simple
> html-Tabelle packen.

Das würde ich persönlich nicht machen, sondern die beiden Komponenten je 
das tun lassen, was sie am Besten können: das Datensammelskript kümmert 
sich um Deine Daten, das WSGI-Skript (Flask) kümmert sich darum, die 
Daten fürs Web aufzubereiten. Die beiden Komponenten können dann 
entweder direkt miteinander kommunizieren, oder -- je nachdem -- kann es 
auch sinnvoller sein, noch eine Infrastrukturkomponente dazwischen zu 
platzieren.

Zunächst einmal ist die Frage, was Du mit Deinen Daten nach deren 
Sammlung zuerst machen möchtest. Sollen Deine Daten verarbeitet, also 
zum Beispiel umgerechnet oder aggregiert werden? Sollen die Daten in 
irgendeiner Weise persistiert, also gespeichert werden, und wenn ja: 
wie?

Für sinnvolle Ratschläge wäre es sicherlich sinnvoll, wenn Du etwas zu 
den Daten sagen könntest, vor allem zu Umfang, Quellen und Struktur, 
dann etwas dazu sagen könntest, ob und wie sie verarbeitet und ob, wie 
und wie lange sie gespeichert werden sollen, und wie Du sie am Ende 
darstellen möchtest, also beispielsweise in Balken- oder 
Liniendiagrammen, nur in Tabellen, oder... richitg, da gibt es drölfzig 
Möglichkeiten, statische, interaktive, und so weiter, und so fort. Diese 
Aspekte erscheinen mir nach der Lektüre Deines Eröffnungsbeitrages noch 
zu diffus, um etwas Kluges dazu zu sagen.

von Ein T. (ein_typ)


Lesenswert?

Alex Z. schrieb:
> Die Lösung heißt WebSocket, kannst du in deinem Flask auch einbauen.

Ja, also, äh... ja, das kann man machen. Aber dann würde ich eher über 
das Modul Flask-SocketIO von Miguel Grinberg (ja, der mit den 
Flask-Tutorials) nachdenken, das auf Websockets aufbaut, aber viele 
nützliche zusätzliche Features der JavaScript-Bibliothek SocketIO 
nutzbar macht.

von Jobst Q. (joquis)


Lesenswert?

Am einfachsten ist es nur die zu erneuernden Daten als 
Varieablendeklaration (vorzugsweise als Arrays) in eine JS-Datei zu 
schreiben. Das ist sehr viel kompakter als Daten in HTML-Form.

Im Init-Skript wird ein Timer installiert, der in Abständen die Daten 
neu anfordert und einige Sekunden danach die Darstellung aktualisiert. 
Das Anfordern der Daten geschieht durch die Neuerstellung eines 
<Script>-Elements. Ein schon bestehendes Elelement mit gleicher ID wird 
vorher entfernt.
1
//--------------------------------------
2
function NewData(){
3
var script;
4
var el;
5
6
var old=document.getElementById("newdata");
7
if(old!=null){
8
  document.getElementsByTagName('head')[0].removeChild(old);
9
//  console.log("NewData:script-aufruf entfernt");
10
  }
11
12
script = document.createElement("script");
13
14
script.src = "./update.js";
15
script.type = "text/javascript";
16
script.async = "true";
17
script.id = "newdata";
18
19
el=document.getElementsByTagName("head")[0];
20
el.appendChild(script);
21
22
//console.log("NewData:script-aufruf"+ script+" erzeugt");
23
}

: Bearbeitet durch User
von Εrnst B. (ernst)


Lesenswert?

Jobst Q. schrieb:
> Am einfachsten

Und dann lieferst du so einen umständlichen und veralteten code?
Wo hast du den ausgegraben, stammt wohl noch aus der Zeit vor JSON?
1
  setInterval(async ()=>{
2
    data = await (await fetch("update.json")).json();
3
  }, 1000);

: Bearbeitet durch User
von Gon T. (gonta)


Lesenswert?

Steve van de Grens schrieb:
> Wer in seinem Browser Javascript deaktiviert, ist selber Schuld bzw.

Der schont den Akku seines Laptops oder Tabletts und bekommt
regelmässig keine Werbung zu sehen.

 > kann das selber umstellen. Ich denke, man muss für diese Leute keine
> Sonderlocke mehr vorsehen, das ist nicht mehr zeitgemäß.
Was zeitgemäß ist, bestimmt wohl immer noch der Nutzer.

> Hier ein altes Beispiel, mit dem ich die "Navigationsleiste" auf meiner
> Hompepage nachlade:
Eine von den kaputten Webseiten, die als HTML-Version keine Navigation 
haben?

Der besondere Lacher: Eine Kommerzseite, deren Javascriptnavigation
bei einem Zoomfaktor von 150 % einfach vom Bildschirm verschwand,
und dann navigationslos daherkam?
Was für ein Dreck.

Genau wie die "Neue und dynamische" Seite der Fahrplanauskunft
der Deutschen Bahn.

von Jobst Q. (joquis)


Lesenswert?

Εrnst B. schrieb:
> Jobst Q. schrieb:
>> Am einfachsten
>
> Und dann lieferst du so einen umständlichen und veralteten code?
> Wo hast du den ausgegraben, stammt wohl noch aus der Zeit vor JSON?
>
>
1
>   setInterval(async ()=>{
2
>     data = await (await fetch("update.json")).json();
3
>   }, 1000);
4
>
Ich habe ihn nicht ausgegraben, sondern aus einfachen 
Javascript-Funktionen entwickelt. Die Umständlichkeit deines Codes ist 
nur versteckt, wenn man ihn verstehen will, ist nichts mehr einfach. Nur 
weil es etwas wie JSON gibt, muss man es nicht verwenden, wenn es ohne 
besser geht.

Es geht um die Einfachheit der Bereitstellung der Daten im Server, was 
gerade im Embedded-Bereich von Bedeutung ist. Und 
JS-Variablenzuweisungen sind deutlich einfacher als das JSON-Format. Zum 
Beispiel:
1
var AnaV=[19464,6400,18680,22708,16224,124,18888,21956,6584,17904,25104,
2
8,23412,3700,5800,2972,18000,31000,30600,49600,30000,30600,832,12788,13436,
3
13177,13431,3081,4072,0,6600,0,10800,0,0,16318,0,20100,18136,0,0,0,9590,
4
9547,900,41848,4444,2036,4320,0,];
5
var DigV=[1,0,0,1,0,0,1,0,0,1,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,1,
6
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,
7
0,1,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,1,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
8
0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,];
9
var UnixTime=1707078289;

Es mag Anwendungen geben, wo JSON Vorteile bringt, sehe ich hier aber 
nicht als gegeben.

von Kolja L. (kolja82)


Lesenswert?

Keiner von euch Spezies kennt die genauen Anforderungen an das 
Datenformat und ihr kloppt euch...

Btw, der TO hat sich noch nie zu irgendeiner Antwort geäußert. Selbst 
wenn er nochmal wieder hier aufschlägt sind solche DetailKriege doch 
nichts was ihm (derzeit) weiterhilft.

Ich beobachte weiter, warte auf den TO und hoffe auf nicht zu viel 
vorrauseilende Antworten.

von M. M. (maik3)


Lesenswert?

Kolja L. schrieb:
> Btw, der TO hat sich noch nie zu irgendeiner Antwort geäußert. Selbst
> wenn er nochmal wieder hier aufschlägt sind solche DetailKriege doch
> nichts was ihm (derzeit) weiterhilft.

Genau, der TO ist nämlich etwas irritiert von den Antworten und musste 
erst abwägen ob es noch zielführend ist diesen Thread fortzusetzen.

Vor allem bin ich aber irritiert dass hier Code gepostet, JSON und 
Javascript  in Frage gestellt und Buzzwörter wie UX, DX und SEO 
eingesträut werden.

Die technische Umsetzung krieg ich hin, bzw. habe ich bereits 
hinbekommen, sowohl Methode 1 (Server liefert bettet Daten in ein 
template ein und liefert statisches html) als auch Methode 2 (Browser 
lädt zyklisch Daten per REST/JSON nach und aktualisiert den html-Code).

Ich werde Lösung 2 behalten weil sich die Seite dort selber partiell 
aktualisieren kann (ja, würde mit Websockets auch gehen) und 
Datensammlung und deren Darstellung im Frontend sauber getrennt sind. 
Außerdem kann die REST-Api auch anderweitig (Script, Logger) genutzt 
werden.

Die Frage war wirklich nur zu welcher Methode ihr tendiert und wieso, 
welche Vor- und Nachteile diese noch haben die ich evtl. nicht sehe.

: Bearbeitet durch User
Beitrag #7596083 wurde vom Autor gelöscht.
von Kolja L. (kolja82)


Lesenswert?

M. M. schrieb:
> Buzzwörter wie UX, DX und SEO eingesträut werden.

Da ich nicht weiß, wissen kann, wer die Seite programmiert und wer sie 
nutzen soll, hab ich es halt allgemein formuliert 😉

So hatte ich deine Frage auch verstanden.

Den Punkt, den du noch genannt hast, habe ich allerdings vergessen. Mit 
einer API bist du natürlich flexibler was die Ausgabe der Daten angeht.

Dann noch viel Erfolg

von Frank E. (Firma: Q3) (qualidat)


Lesenswert?

Im gesamten Thread sehe ich nichts zum Thema Aktualisierungs-Frequenz, 
was aber m.E. entscheidend für die Wahl der Mittel wäre. Sollen die 
fremden Daten jedesmal aktualisiert werden, sobald jemand die HTML-Seite 
aufrufen wird? Sicher nicht, oder?

Mein Vorschlag: Der Sammler-Daemon aktualisiert autonm in einer 
angemessenen Frequenz die Daten in eine Datenbank hinein. Entweder 
überschreibt er die alten mit den aktuellen Daten oder er legt jedesmal 
neue Datensätze an. Dann könnte man im Web-Interface eventuell auch die 
Historie betrachten oder Diagramme daraus machen ...

Die Webseite ist ebenfalls autonom und ezeugt bei Aufruf aus der 
Datenbank heraus jeweils eine (momentan) statische Ansicht. Das könnte 
man mit Apache/PHP oder node.js machen.

WebSocket oder Ajax/Promises usw. sind m.E. nur sinnvoll, wenn die 
Aktualiserungsfrequenz sehr hoch ist, während man auf der Webseite 
verweilt. Aber zur Frequenz wurde ja bisher nichts mitgeteilt.

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.