Auch ich bevorzuge eine JSON-Antwort mit clientseitiger HTML-Erstellungslogik.
Leider sind die meisten echten clientseitigen HTML-Schreibskripte fehlerhaft und enthalten viele HTML-Injection-Fehler, die leicht zu Cross-Site-Scripting-Sicherheitslücken werden können. Ich glaube, man glaubt, dass man, weil man mit seinem eigenen Server und nicht direkt mit einem feindlichen Benutzer kommuniziert, irgendwie "sicher" ist und ohne korrekte Zeichenketten auskommt, wenn man sie in HTML interpoliert. Das ist natürlich Blödsinn.
Ich sehe immer Sachen wie:
$('#mydiv').append('<em>Deleted '+response.title+'!</em>');
oder:
mydiv.innerHTML= '<p>Renamed to '+response.name+'</p>;
oder auch Resigs Microtemplating-Hack, bei dem standardmäßig kein HTML-Escaping vorgenommen wird. Kommen Sie auf , Leute! Wir haben gerade erst damit begonnen, die Hinterlassenschaften kaputter PHP-Skripte zu beseitigen, die serverseitige XSS ausnutzen, und jetzt wollen Sie eine ganz neue, massive Reihe von clientseitigen XSS-Exploits einführen?
Seufz. Das ist die Verlockung der Streicher. Wir glauben, sie zu verstehen, und können sie beliebig aneinander reihen. Aber Strings sind tückisch, mit versteckten Kontexten und Escaping-Anforderungen. Wenn Sie HTML auf der Client-Seite generieren müssen, benötigen Sie eine Funktion wie diese:
function h(s) {
return s.split('&').join('&').split('<').join('<').split('"').join('"');
}
mydiv.innerHTML= '<p>Renamed to '+h(response.name)+'</p>;
Ich persönlich bevorzuge jedoch DOM-Methoden. Wie bei der Parametrisierung von SQL wird bei der Verwendung von DOM-Methoden das Schleudern von Zeichenketten vermieden, indem rohe Zeichenketten direkt an die Komponenten übergeben werden, die sie verbrauchen sollen. OK, das Problem mit dem DOM ist, dass es ziemlich langatmig ist:
var p= document.createElement('p');
p.appendChild(document.createTextNode('Renamed to '+response.name))
mydiv.appendChild(p);
Aber Sie können immer Hilfsfunktionen definieren, um das zu reduzieren, z. B.:
mydiv.appendChild(makeElement('p', {}, 'Renamed to'+response.name));
(Die neue Elementerstellung in jQuery 1.4 verwendet einen ähnlichen Stil).