Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Gluecksrad

275 views
Skip to first unread message

Klaus Ketelaer

unread,
Nov 11, 2016, 11:19:32 AM11/11/16
to
Hallo zusammen,

ich bin, was JavaScipt, Ajax, etc. betrifft so ziemlich
frei von jedem Wissen.

Dummerweise muss ich ich kurzfristig so etwas wie ein
Glücksrad erstellen, also eine "rotierende Torte", die
langsam ausläuft und bei einem Stück der Torte stehen
bleibt.

So wie ich das sehe, kann ich dabei meine gewohnten
Werkzeuge Perl, Php, Html, CSS, ... weitestgehend
vergessen.

Was ich bisher mittels Googel gefunden habe, das bekomme
ich irgendwie nicht ans laufen.

Hat zufällig jemand einen Link zu einem funktionierenden
Beispielcode, den man auch als Nicht-JavaScript-Coder
halbwegs nachvollziehen kann?

Dank und Gruß

Klaus

Thomas 'PointedEars' Lahn

unread,
Nov 11, 2016, 1:53:00 PM11/11/16
to
Klaus Ketelaer wrote:

> [Glücksrad bauen]
> Was ich bisher mittels Googel gefunden habe, das bekomme
> ich irgendwie nicht ans laufen.
>
> Hat zufällig jemand einen Link zu einem funktionierenden
> Beispielcode, den man auch als Nicht-JavaScript-Coder
> halbwegs nachvollziehen kann?

<http://www.tty1.net/smart-questions_de.html>

--
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not cc me. / Bitte keine Kopien per E-Mail.

Klaus Ketelaer

unread,
Nov 12, 2016, 6:24:21 AM11/12/16
to
Am 11.11.2016 um 19:52 schrieb Thomas 'PointedEars' Lahn:
> Klaus Ketelaer wrote:
>
[...]

Vielen Dank für deine schnelle Hilfe.

Dank Deiner kompetenten Ratschläge konnte
ich das Problem schnell lösen und habe nun
ein funktionierendes Glücksrad.

Gruß Klaus

Thomas 'PointedEars' Lahn

unread,
Nov 13, 2016, 2:49:56 PM11/13/16
to
Klaus Ketelaer wrote:

> Vielen Dank für deine schnelle Hilfe.

Gern geschehen.

> Dank Deiner kompetenten Ratschläge konnte
> ich das Problem schnell lösen und habe nun
> ein funktionierendes Glücksrad.

Super.

Arno Welzel

unread,
Nov 13, 2016, 7:52:27 PM11/13/16
to
Klaus Ketelaer schrieb:

> ich bin, was JavaScipt, Ajax, etc. betrifft so ziemlich
> frei von jedem Wissen.
>
> Dummerweise muss ich ich kurzfristig so etwas wie ein
> Glücksrad erstellen, also eine "rotierende Torte", die
> langsam ausläuft und bei einem Stück der Torte stehen
> bleibt.

Was heisst "muss ich"? Wenn Du es nicht selber kannst, dann wirst Du
wohl jemanden beauftragen müssen, das umzusetzen. Kostenlos aber wohl
eher nicht.

> Hat zufällig jemand einen Link zu einem funktionierenden
> Beispielcode, den man auch als Nicht-JavaScript-Coder
> halbwegs nachvollziehen kann?

Fertige "Glücksrad-Animation"? Nö, ist mir nichts bekannt. Ich würde
halt mit CSS-Manipulation anfangen - also eine Bitmap von einem
Glücksrad nehmen und diese mit der CSS-Eigenschaft transform:rotate
drehen lassen.


--
Arno Welzel
https://arnowelzel.de
http://de-rec-fahrrad.de
http://fahrradzukunft.de

Thomas 'PointedEars' Lahn

unread,
Nov 13, 2016, 8:25:05 PM11/13/16
to
Arno Welzel wrote:

> Fertige "Glücksrad-Animation"? Nö, ist mir nichts bekannt. Ich würde
> halt mit CSS-Manipulation anfangen - also eine Bitmap von einem
> Glücksrad nehmen und diese mit der CSS-Eigenschaft transform:rotate
> drehen lassen.

JFTR: Die CSS-Eigenschaft heisst “transform”. rotate() ist eine CSS-
Funktion, deren Aufruf als Wert dieser Eigenschaft angegeben werden kann.

Die Animation sollte man auch mit CSS realisieren (animation-Eigenschaft);
starten kann man sie dann mit clientseitigem Scripting.

Besser als mit einer Bitmap-Grafik wird es aber mit Scalable *Vector*
Graphics (SVG) aussehen. Das wäre auch barriereärmer.

Arno Welzel

unread,
Nov 14, 2016, 4:19:15 AM11/14/16
to
Thomas 'PointedEars' Lahn schrieb:

> Arno Welzel wrote:
>
>> Fertige "Glücksrad-Animation"? Nö, ist mir nichts bekannt. Ich würde
>> halt mit CSS-Manipulation anfangen - also eine Bitmap von einem
>> Glücksrad nehmen und diese mit der CSS-Eigenschaft transform:rotate
>> drehen lassen.
>
> JFTR: Die CSS-Eigenschaft heisst “transform”. rotate() ist eine CSS-
> Funktion, deren Aufruf als Wert dieser Eigenschaft angegeben werden kann.
>
> Die Animation sollte man auch mit CSS realisieren (animation-Eigenschaft);
> starten kann man sie dann mit clientseitigem Scripting.
>
> Besser als mit einer Bitmap-Grafik wird es aber mit Scalable *Vector*
> Graphics (SVG) aussehen. Das wäre auch barriereärmer.

Danke für die Ergänzung. Aber wieso? Ich dachte, der Fragesteller soll
Dir erstmal eine richtige Frage formulieren?


--
Arno Welzel
https://arnowelzel.de
https://de-rec-fahrrad.de
http://fahrradzukunft.de

Thomas 'PointedEars' Lahn

unread,
Nov 14, 2016, 4:57:42 AM11/14/16
to
Arno Welzel wrote:

> Danke für die Ergänzung.

Es war auch eine Korrektur.

> Aber wieso?

Weshalb nicht?

> Ich dachte, der Fragesteller soll Dir erstmal eine richtige Frage
> formulieren?

Ich weiss nicht, was Du dachtest.

Klaus Ketelaer

unread,
Nov 14, 2016, 6:41:05 PM11/14/16
to
Muss ich mich jetzt schämen, weil ich keine
Fragen mehr habe?

SCNR

Gruß Klaus

Arno Welzel

unread,
Nov 15, 2016, 2:38:22 AM11/15/16
to
Thomas 'PointedEars' Lahn schrieb:

> Arno Welzel wrote:
>
>> Danke für die Ergänzung.
>
> Es war auch eine Korrektur.

Ja, im Sinne von Rosinenausscheidung, dass bei einer Angabe wie

.myclass {
transform:rotate(30deg);
}

nur "transform" die Eigenschaft ist und der Teil ab "rotate" eine
Funktion ist, auch wenn man es trotzdem genau so wie oben gezeigt, benutzt.

>> Aber wieso?
>
> Weshalb nicht?
>
>> Ich dachte, der Fragesteller soll Dir erstmal eine richtige Frage
>> formulieren?
>
> Ich weiss nicht, was Du dachtest.

Deswegen schreibe ich es, damit Du es weißt. Und was sollte dann der
Verweis auf <http://www.tty1.net/smart-questions_de.html>?

Klaus Ketelaer

unread,
Nov 15, 2016, 11:21:39 AM11/15/16
to
Hallo zusammen,

ich sende aus meinem Glücksrad heraus Daten an ein PHP-Script,
das die Daten dann speichert.

var request = new XMLHttpRequest();
var myUrl = wheel.url + '/save.php'
+ '?ip=' + wheel.ip
+ '&clicks=1'
+ '&type=' + wheel.seg_type;
request.open('get', myUrl, false);
request.send();

Nun muss ich die aktualisierte Daten wieder zurücklesen.

Irgendwie kapiere ich den umgekehrten Weg nicht.

Damit es auch der Thomas versteht(SCNR):
Ich muss Daten aus einem PHP Script heraus an eine laufende
JavaScript Anwendung schicken.

Das Script kann nicht neu gestartet werden! Die Seite kann
nicht refresht(F5) werden!

Wer hat denn mal ein verständliches Beispiel für mich.

Gruß Klaus

Thomas 'PointedEars' Lahn

unread,
Nov 15, 2016, 1:27:49 PM11/15/16
to
Klaus Ketelaer wrote:

> ich sende aus meinem Glücksrad heraus Daten an ein PHP-Script,
> das die Daten dann speichert.
>
> var request = new XMLHttpRequest();
> var myUrl = wheel.url + '/save.php'
> + '?ip=' + wheel.ip
> + '&clicks=1'
> + '&type=' + wheel.seg_type;

Sicherer wäre es, die Werte im query-part mit encodeURIComponent() zu
prozent-codieren.

Was ist “wheel.ip”?

> request.open('get', myUrl, false);

Das solltest Du nicht tun. Wenn das dritte Argument von
XMLHTTPRequest::open() “false” ist, dann wird der Request synchron
behandelt, das heisst das Script blockiert den Browser oder zumindest das
Browser-Fenster/-Tab solange, bis der Server antwortet oder ein Timeout
eintritt.

Diese Form des Requests ist nicht nur benutzerunfreundlich, sie wird auch
gemäss Browserherstellern zukünftig nicht mehr unterstützt werden.

Richtig ist stattdessen:

request.open("GET", myUrl, true);

Normalerweise will man ausserdem wissen, ob der Request erfolgreich war und
was der Server geantwortet hat, würde deshalb nach diesem Aufruf einen
Event-Listener registrieren. Entweder

request.onload = function (event) {
// Zugriff auf event.target.status und event.target.response*
};

request.onerror = function (event) {
// Zugriff auf event.target.status und event.target.response*
};

oder, für den Fall, dass das noch nicht unterstützt wird,

request.onreadystatechange = function () {
if (request.readyState == 4) {
if (/\b(?:2\d\d|1023|0)\b/.test(request.status))
{
/* Zugriff auf request.response*
}
else
{
/* Zugriff auf request.response*
}
}
};

<https://xhr.spec.whatwg.org/>

Oder man benutzt eine Bibliothek wie mein JSX:http.js, die dies kapselt.

> request.send();

Formal richtig ist:

request.send(null);

Das erste (und einzige) Argument von XHR::send() gibt an, welche Daten im
“message body” an den Server gesendet werden sollen (das braucht man vor
allem für POST-Requests). Nur wenn dieses “null” ist, bleibt der “message
body” per Spezifikation und Implementierung leer.

> Nun muss ich die aktualisierte Daten wieder zurücklesen.
>
> Irgendwie kapiere ich den umgekehrten Weg nicht.

Siehe oben.

> Damit es auch der Thomas versteht(SCNR):
> Ich muss Daten aus einem PHP Script heraus an eine laufende
> JavaScript Anwendung schicken.

<?= $daten ?>

> Das Script kann nicht neu gestartet werden! Die Seite kann
> nicht refresht(F5) werden!

Du meinst wohl “_darf_ nicht”.

> Wer hat denn mal ein verständliches Beispiel für mich.

Schade, Du hast – trotz Anleitung – immer noch nicht gelernt, wie man Fragen
richtig stellt.

Dann bleibt Dir wohl nur Freund Google.

Klaus Ketelaer

unread,
Nov 16, 2016, 6:13:38 AM11/16/16
to
Am 15.11.2016 um 19:27 schrieb Thomas 'PointedEars' Lahn:
> Klaus Ketelaer wrote:
>
> Sicherer wäre es, die Werte im query-part mit encodeURIComponent() zu
> prozent-codieren.
Ja, das stimmt schon, aber das ist mir im Moment zu unleserlich
beim debuggen. Zudem wird eh immer nur sowas wie

http://winner.test/save.php?ip=192.168.0.10&clicks=1&type=1

übergeben, wo eigentlich nichts passieren kann.

>
> Was ist “wheel.ip”?
>
Eine IP-Adresse

>> request.open('get', myUrl, false);
>
> Das solltest Du nicht tun. Wenn das dritte Argument von
> XMLHTTPRequest::open() “false” ist, dann wird der Request synchron
> behandelt, das heisst das Script blockiert den Browser oder zumindest das
> Browser-Fenster/-Tab solange, bis der Server antwortet oder ein Timeout
> eintritt.

Ich hatte ganz bewusst false eingetragen, weil ich eine synchrone
Verarbeitung wollte.
Normalerweise würde ich nach der Verarbeitung die aktuellen Werte
aus der DB zurücklesen, und erst dann weiter arbeiten.
(Leider bin ich zu blöd, richtig zu fragen, wie Letzteres geht.)

>
> Diese Form des Requests ist nicht nur benutzerunfreundlich, sie wird auch
> gemäss Browserherstellern zukünftig nicht mehr unterstützt werden.
>
> Richtig ist stattdessen:
>
> request.open("GET", myUrl, true);
>
Nach meinen Erfordernissen eher nicht. Ich habe das aber trotzdem erst
mal geändert.


> Normalerweise will man ausserdem wissen, ob der Request erfolgreich war und
> was der Server geantwortet hat, würde deshalb nach diesem Aufruf einen
> Event-Listener registrieren. Entweder
>
> request.onload = function (event) {
> // Zugriff auf event.target.status und event.target.response*
> };
>
> request.onerror = function (event) {
> // Zugriff auf event.target.status und event.target.response*
> };
>
> oder, für den Fall, dass das noch nicht unterstützt wird,
>
> request.onreadystatechange = function () {
> if (request.readyState == 4) {
> if (/\b(?:2\d\d|1023|0)\b/.test(request.status))
> {
> /* Zugriff auf request.response*
> }
> else
> {
> /* Zugriff auf request.response*
> }
> }
> };

In Opera, Chrome und Firefox funktioniert alles wunderbar.

Weil es in diesem scheiss IE11 natürlich wieder nicht funktioniert,
habe ich Deine Tipps prompt eingebaut. onreadystatechange hatte ich
bereits implementiert, aber leider nicht verstanden. Der readyState
ist irgendwie immer 4.

Zudem:
Was hilt es mir, wenn der Request in die Hose geht, aber nirgendwo
etwas auszulesen ist? Es wird kein Fehler ausgelöst, und alles was
ich an Fehlermeldungen auslesen kann sind leere Strings.
Gelegentlich gibt es mal einen Fehler 404 (nur im IE), der aber nur
Blödsinn sein kann.

Wenn ich den IE11 starte und die Anwendung ausführe, dann funktioniert
sie 2-3 mal und danach passiert nichts mehr.


>
> <https://xhr.spec.whatwg.org/>
>
Danke

> Oder man benutzt eine Bibliothek wie mein JSX:http.js, die dies kapselt.
>

Mir wäre es egal, was ich benutze, solange es funktioniert und leicht
verständlich ist.

>> request.send();
>
> Formal richtig ist:
>
> request.send(null);
>

Ja, das hatte ich zwischenzeitlich eingebaut.

Dank und Gruß

Klaus

Thomas 'PointedEars' Lahn

unread,
Nov 16, 2016, 6:37:17 AM11/16/16
to
Klaus Ketelaer wrote:

> Am 15.11.2016 um 19:27 schrieb Thomas 'PointedEars' Lahn:
>> Sicherer wäre es, die Werte im query-part mit encodeURIComponent() zu
>> prozent-codieren.
> Ja, das stimmt schon, aber das ist mir im Moment zu unleserlich
> beim debuggen. Zudem wird eh immer nur sowas wie
>
> http://winner.test/save.php?ip=192.168.0.10&clicks=1&type=1
>
> übergeben, wo eigentlich nichts passieren kann.

<https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet#RULE_.235_-_URL_Escape_Before_Inserting_Untrusted_Data_into_HTML_URL_Parameter_Values>

>> Was ist “wheel.ip”?
>>
> Eine IP-Adresse

Weshalb?

> Normalerweise würde ich nach der Verarbeitung die aktuellen Werte
> aus der DB zurücklesen, und erst dann weiter arbeiten.
> (Leider bin ich zu blöd, richtig zu fragen, wie Letzteres geht.)

Tragisch.

>> Normalerweise will man ausserdem wissen, ob der Request erfolgreich war
>> und was der Server geantwortet hat, würde deshalb nach diesem Aufruf
>> einen Event-Listener registrieren. […]
>
> In Opera, Chrome und Firefox funktioniert alles wunderbar.
>
> Weil es in diesem scheiss IE11 natürlich wieder nicht funktioniert,

Gemäss <http://caniuse.com/#search=xmlhttprequest> funktionieren “onload”
und “onerror” ab IE 11.

> habe ich Deine Tipps prompt eingebaut. onreadystatechange hatte ich
> bereits implementiert, aber leider nicht verstanden. Der readyState
> ist irgendwie immer 4.

Zum Schluss ist er das (4 = “FINISHED”). Deshalb muss man dann noch den
Status und die Response-Message abfragen.

AISB: Man darf aber nur Listener für *entweder* onload/onerror *oder*
onreadystatechange registrieren (was sich eignet, findet man mit “typeof”
heraus). Oder wenn man alles registriert, muss man sicherstellen, dass der
Erfolgs-/Fehlerfall nur einmal behandelt wird.

> Zudem:
> Was hilt es mir, wenn der Request in die Hose geht, aber nirgendwo
> etwas auszulesen ist?

Wenn der Request nicht erfolgreich ist, siehst Du das am readyState, am
Status und an der Response; …

> Es wird kein Fehler ausgelöst, und alles was
> ich an Fehlermeldungen auslesen kann sind leere Strings.

… für die letzteren beiden bist *Du* verantwortlich, denn *Du* hast die
Kontrolle über den serverseitigen (PHP-)Code, oder?

> Gelegentlich gibt es mal einen Fehler 404 (nur im IE), der aber nur
> Blödsinn sein kann.

Wie kommst Du darauf?

> Wenn ich den IE11 starte und die Anwendung ausführe, dann funktioniert
> sie 2-3 mal und danach passiert nichts mehr.

Dann machst Du was fhcsal. Von allen IE-Versionen ist der IE 11 der am
wenigsten kaputte.

Christoph M. Becker

unread,
Nov 16, 2016, 6:58:26 AM11/16/16
to
On 16.11.2016 at 12:13, Klaus Ketelaer wrote:

> Ich hatte ganz bewusst false eingetragen, weil ich eine synchrone
> Verarbeitung wollte.

Du vielleicht, aber auch die User? Die ärgern sich nämlich, wenn der
Browser einfriert, weil ein Request mal lange dauert.

> Normalerweise würde ich nach der Verarbeitung die aktuellen Werte
> aus der DB zurücklesen, und erst dann weiter arbeiten.
> (Leider bin ich zu blöd, richtig zu fragen, wie Letzteres geht.)

Im Prinzip kannst Du folgendes machen:

* XHR vorbereiten (inklusive aufsetzen des readystatechange Listeners)
* den asynchronen XHR abschicken
* sofort Feedback geben, dass im Hintergrund etwas verarbeitet
wird, z.B. durch Anzeige eines Spinners

In der Zwischenzeit kann der Anwender im Browser weitermachen. Auf der
Serverseite behandelst Du den Request, und antwortest dann mit den
nötigen Daten (z.B. als JSON); diese können auch einen Fehler
signalisieren (und eine passende Fehlermeldung enthalten). Kommt die
Antwort beim Client an, dann wird automatisch der readystatechange
Listener aufgerufen. Dort dann etwa:

* prüfen auf readyState == 4 (alles andere ignorieren)
* das Feedback, dass etwas verarbeitet wird, wieder zurück nehmen
* prüfen auf status
* falls okay (100 etc.): die empfangenen Daten verarbeiten (für
JSON siehe JSON.parse()[1]), und anzeigen
* andernfalls: Fehler melden

[1]
<https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse>

--
Christoph M. Becker

Arno Welzel

unread,
Nov 16, 2016, 10:19:35 AM11/16/16
to
Klaus Ketelaer schrieb:

[XHR]
> In Opera, Chrome und Firefox funktioniert alles wunderbar.
>
> Weil es in diesem scheiss IE11 natürlich wieder nicht funktioniert,
> habe ich Deine Tipps prompt eingebaut. onreadystatechange hatte ich
> bereits implementiert, aber leider nicht verstanden. Der readyState
> ist irgendwie immer 4.

Vielleicht hilft Dir diese real funktionierende Seite (ja, die geht auch
im IE 11) als Anregung:

<https://arnowelzel.de/wp/tools/teamspeak-serverstatus>

Im Quelltext ab Zeile 146.

Thomas 'PointedEars' Lahn

unread,
Nov 16, 2016, 12:29:10 PM11/16/16
to
Arno Welzel wrote:

> <https://arnowelzel.de/wp/tools/teamspeak-serverstatus>
>
> Im Quelltext ab Zeile 146.

| <script type="text/javascript">
| /* <![CDATA[ */

Die zweite Zeile ist für XHTML sinnvoll, und dann auch nur nötig, wenn das
XHTML-Dokument mit einem XML-Medientyp ausgeliefert wird (was den XML-Parser
triggert) *und* der Inhalt des Elements Markup-Begrenzer wie “<” enthält; in
HTML5 ohne XHTML-Syntax (siehe Dein doctype und Dein “html”-Element) ist sie
unnötiger Unfug.

| function doUpdate() {

Die benutzerdefinierte Funktion sollte in einem eigenen Namespace definiert
werden, um Namenskollisionen zu vermeiden. Die einfachste Möglichkeit dafür
ist die Definition in einer unmittelbar aufgerufenen anonymen Funktion:

(function () {
function doUpdate ()
{
// …
}

…doUpdate…
}());

| try {
| req=new XMLHttpRequest();
| }
| catch(ms) {
| try {
| req=new ActiveXObject("Msxml2.XMLHTTP");
| }
| catch(nonms) {
| try {
| req=new
ActiveXObject("Microsoft.XMLHTTP");
| }
| catch (failed) {
| req = null;
| }
| }
| }
|

Es ist nicht sinnvoll, das XHR-Objekt für jeden Request neu zu erstellen;
es wird bei open() automatisch zurückgesetzt.

Deine Benennung der Exception-Variablen ist unüblich.

Auf MSXML2 zu testen ist in dieser massgeschneiderten Funktion unnötig, da
Du keine der zusätzlichen Features verwendest.

| if(req != null) {
| req.open("GET", "/tools/tss3/status.php?lang=de", true);
|
| req.onreadystatechange = function() {
| switch(req.readyState) {
| case 4:
| if(req.status==200)
| {
|
document.getElementById("stats").innerHTML = req.responseText;
| }
| setTimeout("doUpdate()", 5000);
| break;
|
| default:
| return false;
| break;
| }
| };
|
| req.setRequestHeader("Content-Type","application/x-www-
form-urlencoded");
| req.send(null);
| }

Die switch-Anweisung ist fehlerträchtig (“switch-case fall-through”) und
hier unnötig bis falsch.


Es sollte

var timeout;
// …
timeout = window.setTimeout(doUpdate, 5000);

heissen:

<https://developer.mozilla.org/de/docs/Web/API/WindowTimers/setTimeout#Passing_string_literals>
<https://de.wikipedia.org/wiki/Content_Security_Policy#Verbotene_Konstrukte_und_Alternativen>

window.clearTimeout(timeout) sollte dann onunload aufgerufen werden.


Der Aufruf von XHR::setRequestHeader() ist *so* (ungetestet) fehlerträchtig
und hier unnötig.

| ( function( $ ) {
| $(document).ready(function () {
| setTimeout("doUpdate()", 5000);
| });
| } )( jQuery );

Wenn Du jQuery verwendest (was hier unnötig erscheint), solltest Du auch
jQuery.ajax() verwenden statt einer eigenen Lösung:

<http://api.jquery.com/jQuery.ajax/>


*Nur* jQuery(document).ready(…) in einer anonymen Funktion aufzurufen ist
unnötig fehlerträchtig.


Empfohlen wird, statt jQuery(document).ready(function () { … }) einfach
jQuery(function () { … }) aufzurufen:

<http://api.jquery.com/ready/>

| /* ]]> */

Unfug, siehe oben.

| </script>

Das script-Element sollte sich im head-Element befinden, nicht innerhalb
eines div-Elements innerhalb eines article-Elements. Optimal werden
gemeinsam genutzte Teile per URI referenziert, wobei die referenzierte
Ressource minimiert ausgeliefert werden kann. Das async- und das defer-
Attribut können dann benutzt werden, um das Script erst dann zu laden,
wenn es benötigt wird.

Arno Welzel

unread,
Nov 16, 2016, 1:13:51 PM11/16/16
to
Thomas 'PointedEars' Lahn schrieb:

> Arno Welzel wrote:
>
>> <https://arnowelzel.de/wp/tools/teamspeak-serverstatus>
>>
>> Im Quelltext ab Zeile 146.
>
> | <script type="text/javascript">
> | /* <![CDATA[ */
>
> Die zweite Zeile ist für XHTML sinnvoll, und dann auch nur nötig, wenn das
> XHTML-Dokument mit einem XML-Medientyp ausgeliefert wird (was den XML-Parser
> triggert) *und* der Inhalt des Elements Markup-Begrenzer wie “<” enthält; in
> HTML5 ohne XHTML-Syntax (siehe Dein doctype und Dein “html”-Element) ist sie
> unnötiger Unfug.

Das Script ist schon *sehr* alt und solche Sachen übersieht man dabei
gerne mal.

ZU den übrigen Punkten: Danke für deine Anmerkungen. Ich werde trotzdem
nichts mehr daran ändern, weil das Ding schlicht und ergreifend in allen
aktuellen Browsern funktioniert, unabhängig davon, ob es formal in allen
Details absolut perfekt umgesetzt ist.

Thomas 'PointedEars' Lahn

unread,
Nov 16, 2016, 1:29:45 PM11/16/16
to
Arno Welzel wrote:

> […] Danke für deine Anmerkungen. Ich werde trotzdem nichts mehr daran
> ändern, weil das Ding schlicht und ergreifend in allen aktuellen Browsern
> funktioniert,

Reiner Zufall.

> unabhängig davon, ob es formal in allen Details absolut perfekt umgesetzt
> ist.

Dein Script hat neben Performance- und Sicherheits-Problemen auch logische
Fehler, die ich erwähnt habe. Zum Beispiel gibt es einen Scriptfehler, wenn
Navigation und Update zusammenfallen, weil Du onunload nicht
window.clearTimeout(…) aufrufst.

Arno Welzel

unread,
Nov 17, 2016, 2:22:02 PM11/17/16
to
Thomas 'PointedEars' Lahn schrieb:

> Arno Welzel wrote:
>
>> […] Danke für deine Anmerkungen. Ich werde trotzdem nichts mehr daran
>> ändern, weil das Ding schlicht und ergreifend in allen aktuellen Browsern
>> funktioniert,
>
> Reiner Zufall.

Da habe ich ja großes Glück, dass es in all den Jahren nie Probleme gab
und sich nie jemand gemeldet hat, das bei ihm das Script nicht funktioniert.

>> unabhängig davon, ob es formal in allen Details absolut perfekt umgesetzt
>> ist.
>
> Dein Script hat neben Performance- und Sicherheits-Problemen auch logische

Die theoretischen Sicherheitsprobleme sind in diesem konkreten Fall
irrelevant. Und Performanceprobleme erkenne in der *Praxis* ich keine,
selbst wenn die Performanceunterschiede verschiedener Umsetzungen
theoretisch messbar sein mögen.

Deine Anmerkung zu switch() ist auch eher theoretischer Natur für
Entwickler, die die Verwendung von break an den richtigen Stellen
vergessen und sich nicht bewusst sind, was die Folgen daraus sind.
Praktisch hat es auf mein Script keine Auswirkung, ob ich nun switch
oder if...else nutze.

> Fehler, die ich erwähnt habe. Zum Beispiel gibt es einen Scriptfehler, wenn
> Navigation und Update zusammenfallen, weil Du onunload nicht
> window.clearTimeout(…) aufrufst.

Ja - wenn man es schafft, *exakt* in dem Moment eine Navigation
auszulösen, wenn gerade der Timer die Funktion aufrufen will. Das ist
weder mir noch den etwa 120 Nutzern dieses Scripts auf dem Server bisher
noch nicht gelungen. Aber ich werde das bei Gelegenheit vielleicht noch
ergänzen.

Thomas 'PointedEars' Lahn

unread,
Nov 17, 2016, 9:09:42 PM11/17/16
to
Arno Welzel wrote:

> […] Performanceprobleme erkenne in der *Praxis* ich keine,
> selbst wenn die Performanceunterschiede verschiedener Umsetzungen
> theoretisch messbar sein mögen.

Je länger man Deine Website anschaut, umso mehr Arbeitsspeicher frisst sie,
weil immer mehr davon für immer neue Objekte reserviert werden muss –
unnötiger Weise. Irgendwann wird dann der Tab oder der Browser vom OOM-
Killer abgeschossen oder das System hängt. Das ist nicht nur theoretisch
messbar (was BTW ein Widerspruch in sich ist; Messungen sind immer Praxis).

Über den Rest Deiner DAU-dummen Reaktion breiten wir lieber den Mantel des
Schweigens.

Arno Welzel

unread,
Nov 18, 2016, 11:24:00 AM11/18/16
to
Thomas 'PointedEars' Lahn schrieb:

> Arno Welzel wrote:
>
>> […] Performanceprobleme erkenne in der *Praxis* ich keine,
>> selbst wenn die Performanceunterschiede verschiedener Umsetzungen
>> theoretisch messbar sein mögen.
>
> Je länger man Deine Website anschaut, umso mehr Arbeitsspeicher frisst sie,
> weil immer mehr davon für immer neue Objekte reserviert werden muss –
> unnötiger Weise. Irgendwann wird dann der Tab oder der Browser vom OOM-
> Killer abgeschossen oder das System hängt. Das ist nicht nur theoretisch
> messbar (was BTW ein Widerspruch in sich ist; Messungen sind immer Praxis).

Aha - und welcher Umgebung soll das sein?

Hier mit Linux Mint 14 und Firefox 49 lässt sich das nicht
reproduzieren. Auch nach mehrere Stunden ist der Speicherbedarf nicht
angestiegen, der OOM-Killer wird logischerweise auch nicht aktiv und ein
hängendendes System habe ich ebenfalls nicht.

Eine kurzer Vergleich mit Windows 7 und Firefox 49 sowie IE 11 wie auch
Firefox unter MacOS hat ebenfalls keine Auffälligkeiten gezeigt.

> Über den Rest Deiner DAU-dummen Reaktion breiten wir lieber den Mantel des
> Schweigens.

Zeige mir, was an der verwendeten switch()-Anweisung konkret *falsch*
ist oder lass' es. Und nein, damit meine ich nicht, dass man es auch
anders machen *kann*, sondern wieso man es anders machen *müsste*:

switch(req.readyState) {
case 4:

break;

default:

break;
}

Und zum Thema "Sicherheit": zeige mir, welches ausnutzbare(!")
Sicherheitsproblem bei meiner Verwendung von windows.setTimeout()
übergibt. Und ja, die Problematik von eval() ist mir sehr wohl bewusst
und ja, wenn ich es mal umbaue, werde ich sicher eine andere Lösung
bevorzugen. Mir aber vorzuhalten, der vorhandene Code hätte ein
Sicherheitsproblem, dann aber auf allgemeine Erläuterungen dazu zu
verweisen, ohne das konkrete(!) Problem zu zeigen, ist sinnfrei.

Und zum Thema "theoretische Messung ist Widerspruch": Damit meine ich,
dass man etwas zwar mit Messungen zeigen kann, dass die Theorie einer
schlechteren Performance stimmt, die gemessenen Ergebnisse für die
Praxis aber nicht relevant sind.

Zu guter letzt: Der TeamSpeak-Server wird mit einer Lizenz für 512 User
betrieben und entsprechend rege genutzt und ebenso nutzen sehr viele
Leute das gezeigte Script entweder direkt bei mir auf der Website oder
eingebunden auf einer anderen Site - und das schon seit etlichen Jahren.
Du kannst Dir sicher sein, dass ich es mitbekommen hätte, wenn es dort
ein Problem mit stetig wachsendem Speicherverbrauch oder gar hängenden
Systemen gegeben hätte.

Arno Welzel

unread,
Nov 18, 2016, 11:40:53 AM11/18/16
to
Arno Welzel schrieb:

> Thomas 'PointedEars' Lahn schrieb:
[...]
>> Über den Rest Deiner DAU-dummen Reaktion breiten wir lieber den Mantel des
>> Schweigens.

JFTR:

<https://validator.w3.org/nu/?doc=http%3A%2F%2Fpointedears.de%2Fscripts%2Ftest%2Fes-matrix%2F>

Oder ist das jetzt "ja, da da ist aber schon sooo alt, da bin ich noch
nicht dazu gekommen, das auf einen fehlerfreien Stand zu bringen"?

Thomas 'PointedEars' Lahn

unread,
Nov 18, 2016, 11:56:07 AM11/18/16
to
Arno Welzel wrote:

> Arno Welzel schrieb:
>> Thomas 'PointedEars' Lahn schrieb:
> [...]
>>> Über den Rest Deiner DAU-dummen Reaktion breiten wir lieber den Mantel
>>> des Schweigens.
>
> JFTR:
>
>
<https://validator.w3.org/nu/?doc=http%3A%2F%2Fpointedears.de%2Fscripts%2Ftest%2Fes-matrix%2F>
>
> Oder ist das jetzt "ja, da da ist aber schon sooo alt, da bin ich noch
> nicht dazu gekommen, das auf einen fehlerfreien Stand zu bringen"?

Nein, das Alter spielt dabei keine Rolle.

Aber das natürlich ein Vergleich von Äpfeln mit Birnen, und ausserdem ein
Ad-hominem-Fehlschluss von Dir.

Christoph M. Becker

unread,
Nov 18, 2016, 12:19:09 PM11/18/16
to
Am 18.11.2016 um 17:56 schrieb Thomas 'PointedEars' Lahn:

> […], und ausserdem ein Ad-hominem-Fehlschluss von Dir.

Ich glaube, dass ist in diesem Thread sowieso das Problem. Ist doch
völlig okay, wenn Du, Arno, Deine Website nicht überarbeiten willst. :-)
Aber trotzdem kann es für andere Leser hilfreich sein, wenn Thomas
konstruktive Kritik am Code, den Du ja als Beispiel-Code benannt
hattest, übt. Und dann kann ja jeder für sich entscheiden, ob er lieber
eine if-elseif- oder eine switch-Anweisung verwendet, etc.

--
Christoph M. Becker

Arno Welzel

unread,
Nov 18, 2016, 1:06:48 PM11/18/16
to
Thomas 'PointedEars' Lahn schrieb:

> Arno Welzel wrote:
>
>> Arno Welzel schrieb:
>>> Thomas 'PointedEars' Lahn schrieb:
>> [...]
>>>> Über den Rest Deiner DAU-dummen Reaktion breiten wir lieber den Mantel
>>>> des Schweigens.
>>
>> JFTR:
>>
>>
> <https://validator.w3.org/nu/?doc=http%3A%2F%2Fpointedears.de%2Fscripts%2Ftest%2Fes-matrix%2F>
>>
>> Oder ist das jetzt "ja, da da ist aber schon sooo alt, da bin ich noch
>> nicht dazu gekommen, das auf einen fehlerfreien Stand zu bringen"?
>
> Nein, das Alter spielt dabei keine Rolle.
>
> Aber das natürlich ein Vergleich von Äpfeln mit Birnen, und ausserdem ein
> Ad-hominem-Fehlschluss von Dir.

Was erwartest Du bei "Deiner DAU-dummen Reaktionen"?

Arno Welzel

unread,
Nov 18, 2016, 1:15:03 PM11/18/16
to
Christoph M. Becker schrieb:
Thomas Kritik war halt nur teilweise "konstruktiv". Wer die Wortwahl
"unnötiger Unfug" und "unnötig bis falsch" anbringt zu Dingen, die rein
faktisch keinerlei negativen Einfluss im konkreten Fall haben, muss sich
auch gefallen lassen, dass man seine eigenen Veröffentlichtungen
ebenfalls kritisch begutachtet.

Thomas 'PointedEars' Lahn

unread,
Nov 18, 2016, 2:06:02 PM11/18/16
to
Arno Welzel wrote:

> Christoph M. Becker schrieb:
>> Am 18.11.2016 um 17:56 schrieb Thomas 'PointedEars' Lahn:
>>> […], und ausserdem ein Ad-hominem-Fehlschluss von Dir.
>> Ich glaube, dass ist in diesem Thread sowieso das Problem. Ist doch
>> völlig okay, wenn Du, Arno, Deine Website nicht überarbeiten willst. :-)
>> Aber trotzdem kann es für andere Leser hilfreich sein, wenn Thomas
>> konstruktive Kritik am Code, den Du ja als Beispiel-Code benannt
>> hattest, übt. Und dann kann ja jeder für sich entscheiden, ob er lieber
>> eine if-elseif- oder eine switch-Anweisung verwendet, etc.
>
> Thomas Kritik war halt nur teilweise "konstruktiv".

Du irrst.

> Wer die Wortwahl "unnötiger Unfug" und "unnötig bis falsch" anbringt zu
> Dingen, die rein faktisch keinerlei negativen Einfluss im konkreten Fall
> haben, […]

Behauptest Du. Abgesehen davon bedeutet „unnötiger Unfug“ einfach „lass
diesen Quatsch besser weg, Du brauchst das nicht“ und „unnötig bis falsch“
kann man mit gutem Willen als „Du handelst Dir damit Probleme ein, mach es
besser anders“ verstehen (dass eine if-else-Anweisung funktional äquivalent
zu einem einer *korrekten* switch-case-default-Anweisung mit *einem* “case”
ist, aber demgegenüber weniger fehlerträchtig, habe ich nicht angenommen,
Dir oder den Mitlesern erklären zu müssen).

> muss sich auch gefallen lassen, dass man seine eigenen Veröffentlichtungen
> ebenfalls kritisch begutachtet.

*Deine* "Kritik" war jedenfalls nicht mal *ansatzweise* konstruktiv. Sie
war hämisch formuliert (der Form nach «tu quoque»), und sie war *verletzend*
gemeint. Das weisst Du auch.

Leider hast Du seit unserer letzten Auseinandersetzung in diesem
Zusammenhang, bei dem Du Dich befleissigt fühltest, als Reaktion auf eine
sachliche Kritik von mir in der Newsgroup auf meine Job-Profile bei XING
und/oder LinkedIn (ich erinnere mich nicht mehr genau welche) zu verweisen,
aus denen hervorging, dass ich zu der Zeit auf Stellensuche war – was Du
entsprechend hämisch kommentiertest –, *nichts* dazugelernt.

Score adjusted, F'up2 de.soc.usenet

Thomas 'PointedEars' Lahn

unread,
Nov 18, 2016, 2:15:02 PM11/18/16
to
Arno Welzel wrote:

> Thomas 'PointedEars' Lahn schrieb:
>> Arno Welzel wrote:
>>> Arno Welzel schrieb:
>>>> Thomas 'PointedEars' Lahn schrieb:
>>> [...]
>>>>> Über den Rest Deiner DAU-dummen Reaktion breiten wir lieber den Mantel
>>>>> des Schweigens.
>>> JFTR:
>>
<https://validator.w3.org/nu/?doc=http%3A%2F%2Fpointedears.de%2Fscripts%2Ftest%2Fes-matrix%2F>
>>>
>>> Oder ist das jetzt "ja, da da ist aber schon sooo alt, da bin ich noch
>>> nicht dazu gekommen, das auf einen fehlerfreien Stand zu bringen"?
>> Nein, das Alter spielt dabei keine Rolle.
>>
>> Aber das natürlich ein Vergleich von Äpfeln mit Birnen, und ausserdem ein
>> Ad-hominem-Fehlschluss von Dir.
>
> Was erwartest Du bei "Deiner DAU-dummen Reaktionen"?

Ein Nachdenken Deinerseits, weshalb ich das so formuliert habe.

JFTR: Es ist ein Äpfel-mit-Birnen-Vergleich, weil ich erstens Dein *Script*
kritisierte und Du mein *Markup*. Und zweitens ist die ECMAScript Support
Matrix mit derzeit *20'104* überwiegend aus *eigenem* Code und Datenbank
*generierten* Zeilen HTML dann doch ein *klein wenig* komplexer ist als Dein
TeamSpeak-Watcher mit *263* Zeilen HTML basierend auf mehr oder weniger
*vorgefertigten WordPress-Templates*. (Das Zeilenverhältnis beim für den
hier bei einem zulässigen Vergleich nicht relevanten JS/ES-Code sieht
übrigens ähnlich aus.)


kopfschüttelnd,

Thomas 'PointedEars' Lahn

unread,
Nov 18, 2016, 2:16:07 PM11/18/16
to
Arno Welzel wrote:

> Thomas 'PointedEars' Lahn schrieb:
>> Arno Welzel wrote:
>>> Arno Welzel schrieb:
>>>> Thomas 'PointedEars' Lahn schrieb:
>>> [...]
>>>>> Über den Rest Deiner DAU-dummen Reaktion breiten wir lieber den Mantel
>>>>> des Schweigens.
>>> JFTR:
>>
<https://validator.w3.org/nu/?doc=http%3A%2F%2Fpointedears.de%2Fscripts%2Ftest%2Fes-matrix%2F>
>>>
>>> Oder ist das jetzt "ja, da da ist aber schon sooo alt, da bin ich noch
>>> nicht dazu gekommen, das auf einen fehlerfreien Stand zu bringen"?
>> Nein, das Alter spielt dabei keine Rolle.
>>
>> Aber das natürlich ein Vergleich von Äpfeln mit Birnen, und ausserdem ein
>> Ad-hominem-Fehlschluss von Dir.
>
> Was erwartest Du bei "Deiner DAU-dummen Reaktionen"?

Ein Nachdenken Deinerseits, weshalb ich das so formuliert habe.

JFTR: Es ist ein Äpfel-mit-Birnen-Vergleich, weil ich erstens Dein *Script*
kritisierte und Du mein *Markup*. Und zweitens ist die ECMAScript Support
Matrix mit derzeit *20'104* überwiegend aus *eigenem* Code und Datenbank
*generierten* Zeilen HTML dann doch ein *klein wenig* komplexer ist als Dein
TeamSpeak-Watcher mit *263* Zeilen HTML basierend auf mehr oder weniger
*vorgefertigten WordPress-Templates*. (Das Zeilenverhältnis beim für den
hier bei einem zulässigen Vergleich relevanten JS/ES-Code sieht übrigens
ähnlich aus.)


kopfschüttelnd,

Thomas 'PointedEars' Lahn

unread,
Nov 18, 2016, 3:45:02 PM11/18/16
to
Arno Welzel wrote:

> Thomas 'PointedEars' Lahn schrieb:
>> Arno Welzel wrote:
>>> […] Performanceprobleme erkenne in der *Praxis* ich keine,
>>> selbst wenn die Performanceunterschiede verschiedener Umsetzungen
>>> theoretisch messbar sein mögen.
>>
>> Je länger man Deine Website anschaut, umso mehr Arbeitsspeicher frisst
>> sie, weil immer mehr davon für immer neue Objekte reserviert werden muss
>> –
>> unnötiger Weise. Irgendwann wird dann der Tab oder der Browser vom OOM-
>> Killer abgeschossen oder das System hängt. Das ist nicht nur theoretisch
>> messbar (was BTW ein Widerspruch in sich ist; Messungen sind immer
>> Praxis).
>
> Aha - und welcher Umgebung soll das sein?

Chromium “53.0.2785.143 Built on 8.6, running on Debian stretch/sid (64-
bit).” Nach 10 Minuten auf der Website ist der Speicherbedarf des Tabs
(siehe Chromium Task-Manager, Shift+Esc) um ca. 7.14 MiB angestiegen. Man
kann beobachten, wie der Speicherbedarf im 5-Sekunden-Takt von kontinierlich
ansteigt. Das korreliert genau mit dem wiederholten überflüssigen Erzeugen
der XHR-Instanz, wie man in der Spalte “Network” und mit “Profiles”, “Record
Allocation Timeline” sieht (zuerst steigt der Speicherbedarf, dann gibt es
die Netzwerkaktivität).

Start: 21:12 CET
Spalte “Memory”: 60'552 KiB

Ende: 21:22 CET
Spalte “Memory”: 67'312 KiB

Das Ergebnis ist zuverlässig (nach “uncached reload”) reproduzierbar.

Und dabei habe ich *nichts* auf der Website oder im Browser gemacht ausser
gelegentlich zwischen Browser-Task-Manager und Newsreader (nicht im Browser)
hin- und herzuschalten.

Das Problem gibt es nicht nur auf Deiner Website (sondern besonders
problematisch auch bei Facebook und Twitter, die auch über XHR den Status
aktualisieren), aber die Ursache ist dieselbe. Denn wenn man nichts macht
oder XHR richtig macht, passiert es nicht.

> Hier mit Linux Mint 14 und Firefox 49 lässt sich das nicht reproduzieren.
> Auch nach mehrere Stunden ist der Speicherbedarf nicht angestiegen,

Wie misst Du das?

> der OOM-Killer wird logischerweise auch nicht aktiv und ein
> hängendendes System habe ich ebenfalls nicht.

Du solltest auch nicht davon ausgehen, dass Deine Website die einzige ist,
die im Browser angezeigt wird.

> Eine kurzer Vergleich

Was heisst „kurz“?

> mit Windows 7 und Firefox 49 sowie IE 11 wie auch Firefox unter MacOS hat
> ebenfalls keine Auffälligkeiten gezeigt.

Hast Du nur in Firefox 49 und IE 11 getestet?

>> Über den Rest Deiner DAU-dummen Reaktion breiten wir lieber den Mantel
>> des Schweigens.
>
> Zeige mir, was an der verwendeten switch()-Anweisung konkret *falsch*
> ist oder lass' es.

Ich schrieb „_unnötig bis_ falsch“. Es hilft Deiner Argumentation nicht,
wenn Du mich verkürzt wiedergibst.

Weshalb ich das schrieb, dachte ich, sei offensichtlich.

Zur besseren Lesbarkeit habe die Einrückung reduziert und den Quelltext
lesbarer formatiert (auch etwas, an dem Du noch arbeiten kannst):

| req.onreadystatechange = function () {
| switch (req.readyState)
| {
| case 4:
| […]
| break;
|
| default:
| return false;
| break;
| }
| };

Die switch-Anweisung befindet sich *alleinstehend* in einer *Funktion*.

Somit ist die return-Anweisung überflüssig, denn nach der switch-Anweisung
wird die Funktion ohnehin verlassen:

req.onreadystatechange = function () {
switch (req.readyState)
{
case 4:
[…]
break;

default:
break;
}
};

Schreibt man die return-Anweisung hin, ist die zweite break-Anweisung
überflüssig, denn die Funktion wird ja schon durch die return-Anweisung
verlassen:

req.onreadystatechange = function () {
switch (req.readyState)
{
case 4:
[…]
break;

default:
return false;
}
};

Es handelt sich ausserdem um einen Event-Listener, der an eine Event-
Handler-Eigenschaft zugewiesen wurde. Da ist es wesentlich, wie der
Rückgabewert aussieht, denn ein Rückgabewert kann zur Vermeidung der
Standardaktion führen (das ist nicht immer “false”, kann auch “true” sein).
Man sollte also nicht einfach blind einen Wert zurückgeben, weil „das schon
funktioniert“, sondern sich diesen gut überlegen, und im Zweifelsfall "gar
nichts" (d. h. “undefined”) zurückgeben:

req.onreadystatechange = function () {
switch (req.readyState)
{
case 4:
[…]
break;

default:
return;
}
};

Das ist aber schon das Standardverhalten ohne return-Anweisung:

req.onreadystatechange = function () {
switch (req.readyState)
{
case 4:
[…]
break;

default:
}
};

Will man die Funktion erweitern, also Anweisungen nach der switch-Anweisung
hinzufügen, muss man sich daran erinnern, dass da noch eine return-Anweisung
in der switch-Anweisung steht; solange wundert man sich, weshalb der neue
Code manchmal nicht ausgeführt wird:

req.onreadystatechange = function () {
switch (req.readyState)
{
case 4:
[…]
break;

default:
return false;
break;
}

/*
* _Halb_toter Code; kann je nach readyState Probleme verursachen;
* schlecht testbar.
*/
};

In der default-Klausel steht kein (sinnvoller) Code, sie kann also
genausogut weggelassen werden.

req.onreadystatechange = function () {
switch (req.readyState)
{
case 4:
[…]
break;
}
};

Lässt man die default-Klausel nicht weg, so lässt sich dies weniger
fehlerträchtig schreiben:

req.onreadystatechange = function () {
if (req.readyState == 4)
{
// …
}
else
{
return;
}

/*
* _Halb_toter Code; kann je nach readyState Probleme verursachen;
* schlecht testbar.
*/
};

Spätestens jetzt sieht man, dass man den Code stark vereinfachen kann,
wodurch er weniger fehlerträchtig und leichter wartbar wird:

req.onreadystatechange = function () {
if (req.readyState == 4)
{
// …
}

/*
* Evtl. Code hier nun nicht mehr tot; gut testbar.
*/
};

oder (“early return”, “gauntlet“):

req.onreadystatechange = function () {
if (req.readyState != 4) return;

// …

/*
* Evtl. Code hier nun nicht mehr tot; gut testbar.
*/
};

> Und zum Thema "Sicherheit": zeige mir, welches ausnutzbare(!")
> Sicherheitsproblem bei meiner Verwendung von windows.setTimeout()
> übergibt.

Erstens heisst es window.setTimeout().

Zweitens kann der Code, wenn er als String übergeben wird, nur auf global
verfügbare Symbole zugreifen. Das ist für sich schon ein Problem, auch ein
Sicherheitsproblem. Denn jedes fremde Script, was im Dokument geladen wird,
kann die Werte im globalen Ausführungskontext manipulieren, also zum
Beispiel die Funktion überschreiben. Sogar jede Extension und jedes Plugin
kann das, weil der globale Kontext an das Tab/Fenster gekoppelt ist.

Drittens ergibt sich das ausnutzbare Sicherheitsproblem dadurch, dass Du als
Autor nicht Sicherheitsfeatures des Browsers wie Content Security Policy
nutzen kannst, solange Du den Code als String übergibst (siehe Referenz).

Kein heutzutage sinnvoll scriptbarer Browser erfordert noch die String-
Variante. Wie aus der ECMAScript Support Matrix hervorgeht (ausnahmsweise,
weil dieses Feature mit dem Netscape DOM eingeführt wurde, bevor es die
Trennung zwischen Sprache und DOM gab), wird die Variante mit
Funktionsausdruck/-referenz spätestens seit Mozilla 1.0 und Internet
Explorer 5.5 unterstützt. (Das würdest Du unter anderem wissen, wenn Du
unter anderem die ES Matrix auch mal *lesen* würdest.)

Durch die String-Variante ergeben sich also gegenüber der Variante mit
Funktionsausdruck/-referenz *keinerlei* Vorteile und *nur* Nachteile.

> Und ja, die Problematik von eval() ist mir sehr wohl bewusst
> und ja, wenn ich es mal umbaue, werde ich sicher eine andere Lösung
> bevorzugen.

Die Lösung ist trivial; ich hatte sie Dir sogar bereits hingeschrieben.

Somit kann ich nur hoffen, dass ich mit diesem Posting nicht *wieder* meine
kostbare Freizeit (an Dich) verschwendet habe.

Arno Welzel

unread,
Nov 19, 2016, 4:05:04 AM11/19/16
to
Thomas 'PointedEars' Lahn schrieb:

> Arno Welzel wrote:
>
>> Christoph M. Becker schrieb:
>>> Am 18.11.2016 um 17:56 schrieb Thomas 'PointedEars' Lahn:
>>>> […], und ausserdem ein Ad-hominem-Fehlschluss von Dir.
>>> Ich glaube, dass ist in diesem Thread sowieso das Problem. Ist doch
>>> völlig okay, wenn Du, Arno, Deine Website nicht überarbeiten willst. :-)
>>> Aber trotzdem kann es für andere Leser hilfreich sein, wenn Thomas
>>> konstruktive Kritik am Code, den Du ja als Beispiel-Code benannt
>>> hattest, übt. Und dann kann ja jeder für sich entscheiden, ob er lieber
>>> eine if-elseif- oder eine switch-Anweisung verwendet, etc.
>>
>> Thomas Kritik war halt nur teilweise "konstruktiv".
>
> Du irrst.
>
>> Wer die Wortwahl "unnötiger Unfug" und "unnötig bis falsch" anbringt zu
>> Dingen, die rein faktisch keinerlei negativen Einfluss im konkreten Fall
>> haben, […]
>
> Behauptest Du. Abgesehen davon bedeutet „unnötiger Unfug“ einfach „lass

Ja, behaupte ich, weil es so ist.

Die Existenz von

/* <![CDATA[ */
...
/* ]]> */

Hat exakt *keinen* Einfluss auf das Script oder das Dokument, egal ob es
sich um ein XHMTL-Dokument handelt oder HTML5. Es ist in HTML5 nur
überflüssig, stört aber auch nicht.

> diesen Quatsch besser weg, Du brauchst das nicht“ und „unnötig bis falsch“
> kann man mit gutem Willen als „Du handelst Dir damit Probleme ein, mach es
> besser anders“ verstehen (dass eine if-else-Anweisung funktional äquivalent
> zu einem einer *korrekten* switch-case-default-Anweisung mit *einem* “case”
> ist, aber demgegenüber weniger fehlerträchtig, habe ich nicht angenommen,
> Dir oder den Mitlesern erklären zu müssen).

Du hast aber nicht gesagt, dass die Nutzung von switch() generell
problematisch ist, sondern es auf mein konkretes Script bezogen und
kritisiert, dass *meine* konkrete Umsetzung "unnötig bis falsch" ist:

"[...] und hier unnötig bis falsch."

Und genau das stimmt eben nicht. Das Konstrukt ist formal und
syntaktisch völlig korrekt und ob es unnötig ist, ist wohl eher eine
persönliche Meinung.

>> muss sich auch gefallen lassen, dass man seine eigenen Veröffentlichtungen
>> ebenfalls kritisch begutachtet.
>
> *Deine* "Kritik" war jedenfalls nicht mal *ansatzweise* konstruktiv. Sie
> war hämisch formuliert (der Form nach «tu quoque»), und sie war *verletzend*
> gemeint. Das weisst Du auch.

Wenn Du Dich davon verletzt fühlst, dass jemand eine von Dir
veröffentlichte Arbeit durch den W3C-Validator laufen lässt, kann ich
Dir auch nicht helfen. Und nein, die ECMAScript Support Matrix ist auch
keineswegs "privat" und nicht für die Öffentlichkeit bestimmt, sondern
wird gerne von Dir selbst hier genannt und ist auf
<http://pointedears.de> als Menüpunkt recht prominent sichtbar.

> Leider hast Du seit unserer letzten Auseinandersetzung in diesem
> Zusammenhang, bei dem Du Dich befleissigt fühltest, als Reaktion auf eine
> sachliche Kritik von mir in der Newsgroup auf meine Job-Profile bei XING

Das war damals keine sachliche Kritik, sondern unterste Schublade. Und
deshalb habe ich darauf hingewiesen, dass diese Art von Dir sich bei
künftigen Arbeitgebern sicher nicht gut machen wird.

Nebenbei bemerkt habe ich mich für diesen Vorfall sowohl bei Dir
persönlich als auch in der Newsgroup entschuldigt, da er Dich
offensichtlich sehr mitgenommen hatte.

> und/oder LinkedIn (ich erinnere mich nicht mehr genau welche) zu verweisen,
> aus denen hervorging, dass ich zu der Zeit auf Stellensuche war – was Du
> entsprechend hämisch kommentiertest –, *nichts* dazugelernt.

Nein, Du hast nichts dazugelernt. Menschen sind nicht nur logische Wesen.

F'up ignored.

Arno Welzel

unread,
Nov 19, 2016, 4:22:32 AM11/19/16
to
Thomas 'PointedEars' Lahn schrieb:

> Arno Welzel wrote:
>
>> Thomas 'PointedEars' Lahn schrieb:
>>> Arno Welzel wrote:
>>>> Arno Welzel schrieb:
>>>>> Thomas 'PointedEars' Lahn schrieb:
>>>> [...]
>>>>>> Über den Rest Deiner DAU-dummen Reaktion breiten wir lieber den Mantel
>>>>>> des Schweigens.
>>>> JFTR:
>>>
> <https://validator.w3.org/nu/?doc=http%3A%2F%2Fpointedears.de%2Fscripts%2Ftest%2Fes-matrix%2F>
>>>>
>>>> Oder ist das jetzt "ja, da da ist aber schon sooo alt, da bin ich noch
>>>> nicht dazu gekommen, das auf einen fehlerfreien Stand zu bringen"?
>>> Nein, das Alter spielt dabei keine Rolle.
>>>
>>> Aber das natürlich ein Vergleich von Äpfeln mit Birnen, und ausserdem ein
>>> Ad-hominem-Fehlschluss von Dir.
>>
>> Was erwartest Du bei "Deiner DAU-dummen Reaktionen"?
>
> Ein Nachdenken Deinerseits, weshalb ich das so formuliert habe.

Warum die Sachen so sind, wie sie sind, habe ich Dir erklärt und auch
eingeräumt, dass ich den Code bzgl. window.setTimeout() ohne
window.clearTimeout() in Zukunft noch etwas ändern werde. Meine
Ausführung dazu, wann so ein Fehler ausgelöst werden kann, war auch
keinesfalls als Witz gemeint, sondern durchaus ernst. Wenn sich nämlich
massenweise Leute in den letzten Jahrenbei mir wegen Scriptfehlern
beschwert hätten, hätte ich das sicher schon lange geändert. Und ja, die
Leute, die die genannte Website nutzen, kenne ich größtenteils
persönlich oder sie wissen, wer ich bin und würden mich im Falle von
Fehlern auch darauf ansprechen.

Wenn Du derlei Ausführungen als "DAU-dumm" ansiehst, dann empfinde ich
das als "Du bist ein DAU, der keine Ahnung hat, was er eigentlich tut.".

Vielleicht merkst Du mal langsam, wie deine "Hinweise" mitunter ankommen.

> JFTR: Es ist ein Äpfel-mit-Birnen-Vergleich, weil ich erstens Dein *Script*
> kritisierte und Du mein *Markup*. Und zweitens ist die ECMAScript Support
> Matrix mit derzeit *20'104* überwiegend aus *eigenem* Code und Datenbank
> *generierten* Zeilen HTML dann doch ein *klein wenig* komplexer ist als Dein
> TeamSpeak-Watcher mit *263* Zeilen HTML basierend auf mehr oder weniger
> *vorgefertigten WordPress-Templates*. (Das Zeilenverhältnis beim für den
> hier bei einem zulässigen Vergleich relevanten JS/ES-Code sieht übrigens
> ähnlich aus.)

Ich kritisiere deine bisweilen herablassende Art.

Aber wenn Du unbedingt noch einen Schwanzvergleich haben willst, wie
toll Du doch als Entwickler bist und was Du doch für umfangreiche Sachen
gemacht hast:

Man kann auch generiertes HTML korrekt erzeugen und die vermeintlich
"vorgefertigten WordPress-Templates" bei mir sind meine eigene Arbeit,
die nur durch ein vorhandenes Design inspiriert wurde und die Website
nutzt auch etliche Erweiterungen mit insgesamt einigen tausend Zeilen
PHP im Hintergrund.

Arno Welzel

unread,
Nov 19, 2016, 4:38:43 AM11/19/16
to
Danke - damit kann man ja mal was anfangen. So ist das auch bei mir
nachvollziehbar.

Dazu sehe ich gerade:
<https://bugs.chromium.org/p/chromium/issues/detail?id=52411>

> Und dabei habe ich *nichts* auf der Website oder im Browser gemacht ausser
> gelegentlich zwischen Browser-Task-Manager und Newsreader (nicht im Browser)
> hin- und herzuschalten.
>
> Das Problem gibt es nicht nur auf Deiner Website (sondern besonders
> problematisch auch bei Facebook und Twitter, die auch über XHR den Status
> aktualisieren), aber die Ursache ist dieselbe. Denn wenn man nichts macht
> oder XHR richtig macht, passiert es nicht.

Wie macht man denn XHR "richtig"? Ja, das meine ich durchaus ernst.

>> Hier mit Linux Mint 14 und Firefox 49 lässt sich das nicht reproduzieren.
>> Auch nach mehrere Stunden ist der Speicherbedarf nicht angestiegen,
>
> Wie misst Du das?

Indem ich in top prüfe, wieviel Speicher Firefox belegt und mir in
Firefox mit about:memory Messungen von Firefox selbst geben lasse.

>> der OOM-Killer wird logischerweise auch nicht aktiv und ein
>> hängendendes System habe ich ebenfalls nicht.
>
> Du solltest auch nicht davon ausgehen, dass Deine Website die einzige ist,
> die im Browser angezeigt wird.

Das ist aber für die Prüfung ob ein Script zu steigender
Speicherbelegung führt, irrelevant. Wenn ein Browser nur dann
ansteigenden Speicherbedarf hat, wenn er eine bestimmte Kombination von
Websites gleichzeitig geladen hat, ist wohl eher der Browser fehlerhaft.

>> Eine kurzer Vergleich
>
> Was heisst „kurz“?

Ca. 30 Minuten.

>> mit Windows 7 und Firefox 49 sowie IE 11 wie auch Firefox unter MacOS hat
>> ebenfalls keine Auffälligkeiten gezeigt.
>
> Hast Du nur in Firefox 49 und IE 11 getestet?

Ja, weil Du ja nicht genauer gesagt hast, was deine Testumgebung war.
Deswegen habe ich damit mal angefangen. Und wenn es bei zwei Browsern
nicht reproduzierbar ist, gehe ich nicht davon aus, dass es ein
prinzipielles Problem gibt.

[...]
> Somit kann ich nur hoffen, dass ich mit diesem Posting nicht *wieder* meine
> kostbare Freizeit (an Dich) verschwendet habe.

Die Entscheidung, wem Du deine Zeit widmest, ist deine Sache. Aber Danke
für deine umfangreichen Ausführungen.

Arno Welzel

unread,
Nov 19, 2016, 4:56:31 AM11/19/16
to
Arno Welzel schrieb:

> Thomas 'PointedEars' Lahn schrieb:

[XHR verursacht Speicherlecks in Chrome]

>> Chromium “53.0.2785.143 Built on 8.6, running on Debian stretch/sid (64-
>> bit).” Nach 10 Minuten auf der Website ist der Speicherbedarf des Tabs
>> (siehe Chromium Task-Manager, Shift+Esc) um ca. 7.14 MiB angestiegen. Man
>> kann beobachten, wie der Speicherbedarf im 5-Sekunden-Takt von kontinierlich
>> ansteigt. Das korreliert genau mit dem wiederholten überflüssigen Erzeugen
>> der XHR-Instanz, wie man in der Spalte “Network” und mit “Profiles”, “Record
>> Allocation Timeline” sieht (zuerst steigt der Speicherbedarf, dann gibt es
>> die Netzwerkaktivität).
>>
>> Start: 21:12 CET
>> Spalte “Memory”: 60'552 KiB
>>
>> Ende: 21:22 CET
>> Spalte “Memory”: 67'312 KiB
>>
>> Das Ergebnis ist zuverlässig (nach “uncached reload”) reproduzierbar.
>
> Danke - damit kann man ja mal was anfangen. So ist das auch bei mir
> nachvollziehbar.
>
> Dazu sehe ich gerade:
> <https://bugs.chromium.org/p/chromium/issues/detail?id=52411>

Und hier noch:

<http://stackoverflow.com/questions/9806115/memory-leak-with-an-xmlhttprequest-and-setinterval>

Das dürfte als Anregung reichen, wie ich das Problem lösen kann.

Dennoch ist es bemerkenswert, dass es scheinbar nur in Chrome diese
Probleme mit nicht aufgeräumten Instanzen von XMLHttpRequest gibt, die
auch dann noch existieren, wenn der Request schon lange abgearbeitet wurde.

Arno Welzel

unread,
Nov 19, 2016, 5:48:43 AM11/19/16
to
Arno Welzel schrieb:
So - <https://arnowelzel.de/wp/tools/teamspeak-serverstatus> produziert
in Chrome keinen stetig anwachsenden Speicherverbrauch mehr und wurde
auch sonst um einige Altlasten bereinigt. Ich hoffe, es taugt jetzt eher
als gutes Beispiel wie man XHR handhaben kann.

Klaus Ketelaer

unread,
Nov 22, 2016, 3:19:03 PM11/22/16
to
Am 16.11.2016 um 16:19 schrieb Arno Welzel:
> Klaus Ketelaer schrieb:
>
> Vielleicht hilft Dir diese real funktionierende Seite (ja, die geht auch
> im IE 11) als Anregung:
>
> <https://arnowelzel.de/wp/tools/teamspeak-serverstatus>
>
> Im Quelltext ab Zeile 146.

Hallo,
nachdem hier nun wieder etwas "Frieden" eingekehrt ist, möchte
ich mich noch mal melden.

Ich habe Deinen Code mal bei mir eingebaut, der jedoch genau
so reagiert, wie mein eigener Code. Er funktioniert in allen
Browsern, im IE aber nur 3 mal...

Status ist immer 200 under ResponseText immer leer.

Die PHP-Seite zum speichern ist fehlerfrei, und die verwendete
Stored Procedure in der Datenbank auch. Wenn ich die Seite zum
speichern manuell mit dem IE aufrufe, dann kann sie beliebig
oft hintereinander speichern.

Irgendwie kapier ich das nicht...

Gruß Klaus

Thomas 'PointedEars' Lahn

unread,
Nov 22, 2016, 4:13:33 PM11/22/16
to
Klaus Ketelaer wrote:

> Am 16.11.2016 um 16:19 schrieb Arno Welzel:
>> <https://arnowelzel.de/wp/tools/teamspeak-serverstatus>
>>
>> […]
>
> Ich habe Deinen Code mal bei mir eingebaut, der jedoch genau
> so reagiert, wie mein eigener Code. Er funktioniert in allen
> Browsern, im IE aber nur 3 mal...

„Geht nicht“ ist keine Fehlerbeschreibung.

> Status ist immer 200 under ResponseText immer leer.

Mit welchem Code, in welcher Zeile?

> Die PHP-Seite zum speichern ist fehlerfrei,

Woher willst du das wissen? Und es gibt keine "PHP-Seiten".

> und die verwendete Stored Procedure in der Datenbank auch.

Woher willst Du das wissen?

> Wenn ich die Seite zum speichern manuell mit dem IE aufrufe, dann kann sie
> beliebig oft hintereinander speichern.

Was soll das heissen?

> Irgendwie kapier ich das nicht...

Tja, vielleicht bist Du einfach nicht schlau genug dafür. Oder Du trollst.
Beide Möglichkeiten sind inzwischen gleich wahrscheinlich.

In ersterem Fall solltest Du jemanden beauftragen und bezahlen, der sich
damit auskennt.

<http://glasgoogle.de/>
(leider bezüglich Browsern veraltet, aber die Grundaussage stimmt noch)

Klaus Ketelaer

unread,
Nov 22, 2016, 7:08:05 PM11/22/16
to
Am 22.11.2016 um 22:13 schrieb Thomas 'PointedEars' Lahn:
> Klaus Ketelaer wrote:
>
>> Am 16.11.2016 um 16:19 schrieb Arno Welzel:
>>> <https://arnowelzel.de/wp/tools/teamspeak-serverstatus>
>>>
>>> […]
>>
>> Ich habe Deinen Code mal bei mir eingebaut, der jedoch genau
>> so reagiert, wie mein eigener Code. Er funktioniert in allen
>> Browsern, im IE aber nur 3 mal...
>
> „Geht nicht“ ist keine Fehlerbeschreibung.

"Geht nicht" ist die Fehlerbeschreibung für einen Fehler,
für den man keine Fehlerbeschreibung liefern kann...

Der Request wird einfach reaktionslos ignoriert.

>
>> Status ist immer 200 under ResponseText immer leer.
>
> Mit welchem Code, in welcher Zeile?
>
>> Die PHP-Seite zum speichern ist fehlerfrei,
>
> Woher willst du das wissen?

Ich habe die "Seite" geschrieben!

Und es gibt keine "PHP-Seiten".

Bei mir schon. Ich drucke meine Scripte immer aus...


>> und die verwendete Stored Procedure in der Datenbank auch.
>
> Woher willst Du das wissen?

Ich habe das Ding geschrieben!

(Du musst jetzt schreiben, dass es in der Datenbank
keine Dinger gibt.)

>
>> Wenn ich die Seite zum speichern manuell mit dem IE aufrufe, dann kann sie
>> beliebig oft hintereinander speichern.
>
> Was soll das heissen?

Dass soll heißen, dass ich die Url, die sonst per
Get übermittelt wird, in den Brauser eintippe.

(Du musst jetzt schreiben, dass man in den Browser
nix eintippen kann.)


>> Irgendwie kapier ich das nicht...
>
> Tja, vielleicht bist Du einfach nicht schlau genug dafür. Oder Du trollst.
> Beide Möglichkeiten sind inzwischen gleich wahrscheinlich.

Wenn man Tag für Tag durchs Usenet proletet und einem
nur Trolle begegnen, dann leidet man vermutlich an dem
bekannten Autobahnsyndrom.

Wenn Du nicht so unendlich dämlich wärst, dann könntest
Du mit Aussagen wie z.B.

|ich bin, was JavaScipt, Ajax, etc. betrifft so ziemlich
|frei von jedem Wissen.

etwas anfangen. Vermutlich lernen Möchtegern Superstars
wie Du Java (vorsich Lahn Deppentrigger) in 10 Tagen,
und leisten die 10 Stunden "Richtige Arbeit" pro Tag
auch noch mit Links ab.

Dabei bist Du Depp ja noch nicht einmal in der Lage so
etwas wie Sozialverhalten zu lernen. Wie viele Fachgruppen
hast Du in den letzten 10 Jahren durch Dein paranoides
Verhalten zerstört?

Warum verpisst Du Dich nicht in die einzige Gruppe die
zu Deinem Verhalten passt? Dort kannst Du dich dann mit
deinem erfundenen Lametta profilieren.

Und nun tu, was Du am liebsten tust: Justiere deinen
Score und geh kacken...

Gruß Klaus (einer mit einer verdienten Schelle)

xp+fup2°



Thomas 'PointedEars' Lahn

unread,
Nov 22, 2016, 7:21:14 PM11/22/16
to
[F'up2 ignoriert]

Klaus Ketelaer wrote:

> |ich bin, was JavaScipt, Ajax, etc. betrifft so ziemlich
> |frei von jedem Wissen.

Und doch behauptest Du allen Ernstes, einschätzen zu können, ob in diesen
Sprachen bzw. unter Verwendung dieser Technologien geschriebener Code
korrekt ist, weil Du ja „das Ding geschrieben“ hast. Und Leute beleidigen
und verleumden zu dürfen, die jahrelange Erfahrung – privat *und*
beruflich – auf diesem Gebiet haben, und Dir weiter helfen würden, wenn
Du Dich nicht wie ein grosses Baby anstellen und Dir nur *etwas* mehr Mühe
bei der Lösung *Deiner* Probleme geben würdest.

Na, Einbildung ist ja bekanntlich auch eine Bildung.

Arno Welzel

unread,
Nov 23, 2016, 4:06:56 AM11/23/16
to
Klaus Ketelaer schrieb:

> Am 16.11.2016 um 16:19 schrieb Arno Welzel:
>> Klaus Ketelaer schrieb:
>>
>> Vielleicht hilft Dir diese real funktionierende Seite (ja, die geht auch
>> im IE 11) als Anregung:
>>
>> <https://arnowelzel.de/wp/tools/teamspeak-serverstatus>
>>
>> Im Quelltext ab Zeile 146.
>
> Hallo,
> nachdem hier nun wieder etwas "Frieden" eingekehrt ist, möchte
> ich mich noch mal melden.
>
> Ich habe Deinen Code mal bei mir eingebaut, der jedoch genau
> so reagiert, wie mein eigener Code. Er funktioniert in allen
> Browsern, im IE aber nur 3 mal...
>
> Status ist immer 200 under ResponseText immer leer.

Fehlerprotokolle auf dem Server schon angeschaut?

Arno Welzel

unread,
Nov 23, 2016, 4:18:25 AM11/23/16
to
Arno Welzel schrieb:

> Klaus Ketelaer schrieb:
>
>> Am 16.11.2016 um 16:19 schrieb Arno Welzel:
>>> Klaus Ketelaer schrieb:
>>>
>>> Vielleicht hilft Dir diese real funktionierende Seite (ja, die geht auch
>>> im IE 11) als Anregung:
>>>
>>> <https://arnowelzel.de/wp/tools/teamspeak-serverstatus>
>>>
>>> Im Quelltext ab Zeile 146.
>>
>> Hallo,
>> nachdem hier nun wieder etwas "Frieden" eingekehrt ist, möchte
>> ich mich noch mal melden.
>>
>> Ich habe Deinen Code mal bei mir eingebaut, der jedoch genau
>> so reagiert, wie mein eigener Code. Er funktioniert in allen
>> Browsern, im IE aber nur 3 mal...
>>
>> Status ist immer 200 under ResponseText immer leer.
>
> Fehlerprotokolle auf dem Server schon angeschaut?

Nachtrag: IE nutzt seinen HTTP-Cache auch für XHR-Requests - wenn das
Script, was dort per GET abgefragt wird, nicht explizit mit geeigneten
HTTP-Headern Caching verhindert, könnte das auch für unerwartete Effekte
sorgen. Als Workaround könnte man an die URL für den GET-Request noch
die aktuelle Zeit als Parameter anhängen:

var dateNow = new Date();
var timestampNow = dateNow.getTime(); // <- Millisekunden seit 1.1.1970

Besser wäre aber, das Ergebnis für den XHR-Request mit geeigneten
Headern zu schicken - auf die Gefahr hin, dass ich wieder korrigiert
werde, was einen Unsinn verzapfe, der nur "zufällig" funktioniert:

<?php
header('Cache-Control: max-age=0, no-cache, no-store, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0');
header('Pragma: no-cache');
header('Expires: Wed, 11 Jan 1984 05:00:00 GMT');
...

Thomas 'PointedEars' Lahn

unread,
Nov 23, 2016, 6:16:57 AM11/23/16
to
Arno Welzel wrote:

> Arno Welzel schrieb:
>> Klaus Ketelaer schrieb:
>>> Ich habe Deinen Code mal bei mir eingebaut, der jedoch genau
>>> so reagiert, wie mein eigener Code. Er funktioniert in allen
>>> Browsern, im IE aber nur 3 mal...
^^^^^
>>> Status ist immer 200 under ResponseText immer leer.
>>
>> Fehlerprotokolle auf dem Server schon angeschaut?
>
> Nachtrag: IE nutzt seinen HTTP-Cache auch für XHR-Requests -

Nicht nur IE, und gecachet werden die Responses.

> wenn das Script, was dort per GET abgefragt wird, nicht explizit mit
> geeigneten HTTP-Headern Caching verhindert, könnte das auch für
> unerwartete Effekte sorgen. Als Workaround könnte man an die URL für
> den GET-Request noch die aktuelle Zeit als Parameter anhängen:
>
> var dateNow = new Date();
> var timestampNow = dateNow.getTime(); // <- Millisekunden seit 1.1.1970

"…?" + (new Date()).getTime()

> Besser wäre aber, das Ergebnis

… oder schlicht die HTTP-Antwort (“response”)

> für den XHR-Request

= „XMLHTTPRequest-Request“ :->

> mit geeigneten Headern zu schicken - auf die Gefahr hin, dass ich wieder
> korrigiert werde, was einen Unsinn verzapfe, der nur "zufällig"
> funktioniert:
>
> <?php
> header('Cache-Control: max-age=0, no-cache, no-store, must-revalidate');
> header('Cache-Control: post-check=0, pre-check=0');
> header('Pragma: no-cache');
> header('Expires: Wed, 11 Jan 1984 05:00:00 GMT');

Idee gut; Umsetzung basierend auf “cargo cult programming” statt
Minimalclue, daher mangelhaft. Siehe auch:

- <https://www.mnot.net/cache_docs/>
- <https://tools.ietf.org/html/rfc7232#section-2.2>
- <https://tools.ietf.org/html/rfc7234>

[Der 11. Januar 1984 war tatsächlich ein Mittwoch.]

Das alles kann aber nicht das Problem lösen, dass es „im IE aber nur 3 mal“
funktioniert“. Wenn es nur am Caching liegen würde, dann würde es schon
beim zweiten Mal nicht mehr funktionieren. Entweder ist die
Problembeschreibung fhcals oder die vorgeschlagene Lösung nicht zielführend.

Klaus Ketelaer

unread,
Nov 23, 2016, 9:41:06 AM11/23/16
to
Am 23.11.2016 um 10:06 schrieb Arno Welzel:
> Klaus Ketelaer schrieb:
>
>> Am 16.11.2016 um 16:19 schrieb Arno Welzel:
>>> Klaus Ketelaer schrieb:
>>>
>>> Vielleicht hilft Dir diese real funktionierende Seite (ja, die geht auch
>>> im IE 11) als Anregung:
>>>
>>> <https://arnowelzel.de/wp/tools/teamspeak-serverstatus>
>>>
>>> Im Quelltext ab Zeile 146.
>>
>> Hallo,
>> nachdem hier nun wieder etwas "Frieden" eingekehrt ist, möchte
>> ich mich noch mal melden.
>>
>> Ich habe Deinen Code mal bei mir eingebaut, der jedoch genau
>> so reagiert, wie mein eigener Code. Er funktioniert in allen
>> Browsern, im IE aber nur 3 mal...
>>
>> Status ist immer 200 under ResponseText immer leer.
>
> Fehlerprotokolle auf dem Server schon angeschaut?

Ja, natürlich. Wenn der Fehler auftritt, dann gibt es weder im
access.log, noch im error.log einen Eintrag, was IMHO ja auch
logisch ist, wenn der Request in die Hose geht.

JavaScript liefert mir immer nur:
readyState=4,
Status=200,
responseText=<leer>

Das aber auch wenn alles funktioniert hat...

Ich habe Deinen Code zur Anzeige wie folgt angepasst:

doUpdate: function(url) {
document.getElementById("readyState").innerHTML = '-1';
document.getElementById("status").innerHTML = '-1';
document.getElementById("responseText").innerHTML = '*';

if(wheel.request != null) {
wheel.request.open("GET", url, true);

wheel.request.onreadystatechange = function() {
document.getElementById("readyState").innerHTML = 'Readystate: '
+ wheel.request.readyState;
if(wheel.request.readyState == 4) {

document.getElementById("status").innerHTML = 'Status: ' +
wheel.request.status;
document.getElementById("responseText").innerHTML = 'Text: ' +
wheel.request.responseText;

timeout = setTimeout(function() { doUpdate(); }, 5000);
}
else {
document.getElementById("status").innerHTML = 'Status: ' +
wheel.request.status;
document.getElementById("responseText").innerHTML = 'Text: ' +
wheel.request.responseText;
}
}


wheel.request.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
wheel.request.send(null);
// wheel.request.close;
}
},


Kann das vielleicht irgendein Sicherheitsmechanismus vom IE sein?
Mich wundert es, dass es mit einer neuen Browser-Instanz immer
genau 3 mal funktioniert. Dann ist Schluss!

Gruß Klaus



Christoph M. Becker

unread,
Nov 23, 2016, 10:21:09 AM11/23/16
to
Am 23.11.2016 um 15:41 schrieb Klaus Ketelaer:

> Am 23.11.2016 um 10:06 schrieb Arno Welzel:
>
>> Fehlerprotokolle auf dem Server schon angeschaut?
>
> Ja, natürlich. Wenn der Fehler auftritt, dann gibt es weder im
> access.log, noch im error.log einen Eintrag, was IMHO ja auch
> logisch ist, wenn der Request in die Hose geht.

Was heißt "in die Hose geht"? Wird denn der Request überhaupt abgeschickt?

> JavaScript liefert mir immer nur:
> readyState=4,
> Status=200,
> responseText=<leer>
>
> Das aber auch wenn alles funktioniert hat...

Dein Debug-Output liefert immer die zuletzt gesetzten Werte. Auch wenn
kein Request gesendet wurde, wirst Du die selbe Info ca. alle 5 Sekunden
sehen (na ja, so wie der Debug-Output programmiert ist, wirst Du sie
permanent sehen).

Ich empfehle Dir, Dich mit den Entwickler-Tools der Browser vertraut zu
machen, siehe z.B. <http://devtoolsecrets.com/>.

--
Christoph M. Becker

Klaus Ketelaer

unread,
Nov 23, 2016, 10:41:02 AM11/23/16
to
In meinem PHP-Script mache ich am Anfang folgenden, doppelt
gemoppelten Unfug, was das cachen eigentlich unterbinden
sollte:

header("Expires: ".gmdate("D, d M Y H:i:s")." GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Pragma: no-cache");
header("Cache-Control: post-check=0, pre-check=0", false);

echo '<!DOCTYPE html>'.CRLF;
echo '<html lang="de">'.CRLF;
echo ' <head>'.CRLF;
echo ' <meta charset="utf-8" />'.CRLF;
...
echo ' <meta http-equiv="cache-control" content="no-cache"/>'.CRLF;
echo ' <meta http-equiv="pragma" content="no-cache" />'.CRLF;
echo ' <meta http-equiv="expires" content="0" />'.CRLF;

Gruß Klaus

Thomas 'PointedEars' Lahn

unread,
Nov 23, 2016, 3:16:01 PM11/23/16
to
Klaus Ketelaer wrote:

> In meinem PHP-Script mache ich am Anfang folgenden, doppelt
> gemoppelten Unfug, was das cachen eigentlich unterbinden
> sollte:
>
> header("Expires: ".gmdate("D, d M Y H:i:s")." GMT");
> header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
> header("Cache-Control: no-store, no-cache, must-revalidate");
> header("Pragma: no-cache");
> header("Cache-Control: post-check=0, pre-check=0", false);

So weit, so schlecht; siehe andere Antwort.

> echo '<!DOCTYPE html>'.CRLF;
> echo '<html lang="de">'.CRLF;
> echo ' <head>'.CRLF;
> echo ' <meta charset="utf-8" />'.CRLF;

Weshalb generierst Du eine *vollständige* HTML-Antwort für einen *XHR*?

Und das CRLF im Message Body ist … eigenwillig; HTML ist nicht E-Mail.

echo "…\n";

genügt, wobei mehrere echo-Anweisungen aber unnötig fehlerträchtig und
ineffizient sind, vor allem wenn es sich um eine statische Ausgabe handelt.

Das ist *PHP*-*Grundlagenwissen*.

<http://php.net/manual/en/tutorial.firstpage.php>

> ...
> echo ' <meta http-equiv="cache-control" content="no-cache"/>'.CRLF;
> echo ' <meta http-equiv="pragma" content="no-cache" />'.CRLF;
> echo ' <meta http-equiv="expires" content="0" />'.CRLF;

Das interessiert den Browser nicht, denn 1. hat sein HTTP-Client die
entsprechenden HTTP-Headerfelder schon gesehen und 2. wird die Response von
seiner Layout-Engine nicht als statisches Dokument gerendert.

Das ist *HTML*-*Grundlagenwissen*.

<https://www.w3.org/TR/1999/REC-html401-19991224/struct/global.html#h-7.4.4.2>

<https://www.w3.org/TR/2016/REC-html51-20161101/document-metadata.html#the-meta-element>

Peter J. Holzer

unread,
Nov 23, 2016, 4:47:28 PM11/23/16
to
On 2016-11-23 00:08, Klaus Ketelaer <sp...@spambouncer.de> wrote:
> Am 22.11.2016 um 22:13 schrieb Thomas 'PointedEars' Lahn:
>> Klaus Ketelaer wrote:
>>> Die PHP-Seite zum speichern ist fehlerfrei,
>>
>> Woher willst du das wissen?
>
> Ich habe die "Seite" geschrieben!

Ui. Famous last words ...

hp


--
_ | Peter J. Holzer | Fluch der elektronischen Textverarbeitung:
|_|_) | | Man feilt solange an seinen Text um, bis
| | | h...@hjp.at | die Satzbestandteile des Satzes nicht mehr
__/ | http://www.hjp.at/ | zusammenpaßt. -- Ralph Babel

Arno Welzel

unread,
Nov 24, 2016, 3:29:06 PM11/24/16
to
Thomas 'PointedEars' Lahn wrote:

> Arno Welzel wrote:
[...]
>> <?php
>> header('Cache-Control: max-age=0, no-cache, no-store, must-revalidate');
>> header('Cache-Control: post-check=0, pre-check=0');
>> header('Pragma: no-cache');
>> header('Expires: Wed, 11 Jan 1984 05:00:00 GMT');
>
> Idee gut; Umsetzung basierend auf “cargo cult programming” statt
> Minimalclue, daher mangelhaft. Siehe auch:

Nein, basierend auf praktischer Erfahrung mit dem fehlerhaften Verhalten
diverser Browser und Proxies.

> - <https://www.mnot.net/cache_docs/>
> - <https://tools.ietf.org/html/rfc7232#section-2.2>
> - <https://tools.ietf.org/html/rfc7234>
>
> [Der 11. Januar 1984 war tatsächlich ein Mittwoch.]

Ja, das weiss ich, sonst hätte ich es nicht so geschrieben. Oder
dachtest Du, ich wüsste nicht, was ich da schreibe? ;-)

Thomas 'PointedEars' Lahn

unread,
Nov 24, 2016, 4:45:54 PM11/24/16
to
Arno Welzel wrote:

> Thomas 'PointedEars' Lahn wrote:
>> Arno Welzel wrote:
> [...]
>>> <?php
>>> header('Cache-Control: max-age=0, no-cache, no-store, must-revalidate');
>>> header('Cache-Control: post-check=0, pre-check=0');
>>> header('Pragma: no-cache');
>>> header('Expires: Wed, 11 Jan 1984 05:00:00 GMT');
>>
>> Idee gut; Umsetzung basierend auf “cargo cult programming” statt
>> Minimalclue, daher mangelhaft. Siehe auch:
>
> Nein, basierend auf praktischer Erfahrung mit dem fehlerhaften Verhalten
> diverser Browser und Proxies.

FUD, wie auch aus

>> - <https://www.mnot.net/cache_docs/>

hervorgeht.

--
PointedEars
<http://PointedEars.de/faq> | <http://PointedEars.de/es-matrix>
<https://github.com/PointedEars> | <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2

Arno Welzel

unread,
Nov 25, 2016, 5:11:08 PM11/25/16
to
Thomas 'PointedEars' Lahn wrote:

> Arno Welzel wrote:
>
>> Thomas 'PointedEars' Lahn wrote:
>>> Arno Welzel wrote:
>> [...]
>>>> <?php
>>>> header('Cache-Control: max-age=0, no-cache, no-store, must-revalidate');
>>>> header('Cache-Control: post-check=0, pre-check=0');
>>>> header('Pragma: no-cache');
>>>> header('Expires: Wed, 11 Jan 1984 05:00:00 GMT');
>>>
>>> Idee gut; Umsetzung basierend auf “cargo cult programming” statt
>>> Minimalclue, daher mangelhaft. Siehe auch:
>>
>> Nein, basierend auf praktischer Erfahrung mit dem fehlerhaften Verhalten
>> diverser Browser und Proxies.
>
> FUD, wie auch aus
>
>>> - <https://www.mnot.net/cache_docs/>
>
> hervorgeht.

Nein, praktische Erfahrung - also mit realen Browsern und realen
Proxy-Servern in den letzten etwa 20 Jahren, auch wenn ich gerne
einräume, dass manche der damalige Bugs heute nicht mehr relevant sein
mögen.
0 new messages