Ausgewählte Worte zur bevorstehenden Abschaffung von JavaScript Dialogen

Avatar of Chris Coyier
Chris Coyier am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Es ist vielleicht das Allerallereste, das viele Leute in JavaScript lernen

alert("Hello, World");

Eines Tages wachten wir bei CodePen mit einer Flut von Kundensupport-Anfragen auf, da ihre Pens kaputt waren. Das lag letztendlich daran, dass eine Version von Chrome veröffentlicht wurde, bei der alert() in Cross-Origin-Iframes nicht mehr funktionierte. Und alle anderen nativen „JavaScript-Dialoge“ wie confirm(), prompt() und ich-weiß-nicht-was-noch-alles (onbeforeunload?, .htpasswd geschützte Assets?).

Cross-Origin-Iframes sind im Wesentlichen das Herzstück dessen, wie CodePen funktioniert. Sie schreiben Code und wir führen ihn für Sie in einem Iframe aus, der nicht dieselbe Domain wie CodePen selbst teilt, als erste Sicherheitsmaßnahme. Wir hatten keine Vorwarnung oder so etwas gehört, aber ich bin sicher, die Pläne lagen offen.

Ich twitterte aus Verdruss. Ich verstehe, dass es hier potenzielle Sicherheitsbedenken gibt. JavaScript-Dialoge sehen gleich aus, egal ob sie von einem Iframe ausgelöst werden oder nicht. Daher sind sie offenbar bestenfalls verwirrend, wenn sie von einem Iframe ausgelöst werden, insbesondere von einem Cross-Origin-Iframe, bei dem die übergeordnete Seite wahrscheinlich wenig Kontrolle hat. Nun, abgesehen von, wissen Sie, einer Website wie CodePen. Chrome nennt auch Performance-Bedenken, da diese JavaScript-Dialoge naturgemäß den Haupt-Thread blockieren, wenn sie offen sind, was im Wesentlichen alles anhält.

Es gibt jedoch allerlei Sicherheits- und UX-Ärgernisprobleme, die von Iframes ausgehen können. Deshalb gibt es Sandboxing. Ich kann das tun

<iframe sandbox></iframe>

Und dieser Kerl ist abgeriegelt. Wenn ein Formular etwas darin einreichen würde: nein, funktioniert nicht. Was ist, wenn es versucht, einen Download auszulösen? Nein. Gerätespeicherzugriff anfordern? Auf keinen Fall. Es kann nicht einmal JavaScript überhaupt laden. Das heißt, es sei denn, ich lasse es zu

<iframe sandbox="allow-scripts allow-downloads ...etc"></iframe>

Warum also kein Attribut für JavaScript-Dialoge? Ironischerweise gibt es bereits eines: allow-modals. Ich bin mir nicht ganz sicher, warum das nicht ausreicht, aber soweit ich weiß, ist die Zerstörung von JavaScript-Dialogen in Cross-Origin-Iframes nur ein Sprungbrett für das ultimative Ziel: sie komplett von der Webplattform zu entfernen.

Verdammt. Komplett? Das ist das Wort. Stellen Sie sich die Anzahl der Programmier-Tutorials vor, die einfach kaputt gehen werden.

Vorerst ist selbst die Entfernung für Cross-Origin auf Januar 2022 verschoben, aber soweit wir wissen, wird dies fortgesetzt und dann werden weitere Schritte unternommen, um sie vollständig zu entfernen. Dies wird von Chrome angeführt, aber die Statusberichte zeigen, dass sowohl Firefox als auch Safari mit der Änderung einverstanden sind. Außerdem ist dies eine spezifizierte Änderung, also können wir hier buchstäblich überall mit den Fingern wackeln, wenn Sie, wie ich, das Gefühl haben, dass dies nicht besonders gut gehandhabt wurde.

Was uns bisher mitgeteilt wurde, ist die Lösung, postMessage zu verwenden, wenn Sie diese Funktionalität für Cross-Origin-Iframes wirklich unbedingt beibehalten müssen. Dies sendet den String, den der Benutzer in window.alert verwendet, an die übergeordnete Seite und löst den Alarm von dort aus. Ich bin kein großer Fan davon, weil

  1. postMessage ist nicht blockierend wie JavaScript-Dialoge. Das ändert den Anwendungsfluss.
  2. Ich muss Code in den Code der Benutzer injizieren. Das ist neue technische Schuld und es kann die Erwartungen an die erwartete Benutzerausgabe beeinträchtigen (z. B. ein zusätzliches <script> in ihrem HTML hat seltsame Auswirkungen, wie z. B. die Änderung dessen, was :nth-child und ähnliche auswählen).
  3. Ich bin generell besorgt, irgendetwas benutzergeneriertes an ein übergeordnetes Element zur Ausführung zu übergeben. Ich bin sicher, es gibt theoretische Wege, dies sicher zu tun, aber XSS-Angriffsvektoren sind immer überraschend in ihrer Genialität.

Selbst weniger drastische Vorschläge, wie window.alert = console.log, haben im Wesentlichen die gleichen Probleme.

Gestatten Sie mir, das Mikrofon an andere für ihre Meinungen weiterzugeben.

Könnte der Alarm auf das Iframe beschränkt werden, anstatt im übergeordneten Fenster angezeigt zu werden?

Jaden Baptista, Twitter

Ja, bitte! Löst das nicht einen großen Teil davon? Und macht die UX dieser Dialoge nützlicher? Platziert die verdammten Dialoge im <iframe>.

„Brecht das Web nicht.“ zu „Brecht 90% des Webs nicht.“ und jetzt „Brecht das Web, dessen Inhalt wir zustimmen.“ nicht.

Matthew Phillips, Twitter

Ich respektiere den Wunsch, ungelenke Teile [der HTML-Spezifikation] loszuwerden, die als historische Fehler angesehen werden können und Implementierungskomplexität verursachen, aber ich kann das Gefühl nicht loswerden, dass die bestehenden Anwendungsfälle mit sehr wenig Respekt oder Neugier behandelt werden.

Dan Abramov, Twitter

Es ist seltsam für mich, dass dies Teil der HTML-Spezifikation und nicht der JavaScript-Spezifikation ist. Oder?

Ich dachte immer, es gäbe eine Art „Oberste Direktive“, das Web nicht zu brechen? Ich habe buchstäblich webbasierte Spiele gesehen, die alert als „Pause“ verwendeten und die blockierende Natur als Funktion nutzten. Wie: <button onclick="alert('paused')">Pause</button>[.] Lustig, aber wahr.

Ben Lesh, Twitter

Eine Metrik wurde zitiert, die besagt, dass nur 0,006 % aller Seitenaufrufe ein Cross-Origin-Iframe enthalten, das diese Funktionen verwendet, doch

Scheint eine irreführende Metrik für etwas wie confirm() zu sein. Wenn zum Beispiel der Fluss zur Kontolöschung confirm() verwendet und aufgrund einer Änderung daran kaputt geht, bedeutet das nicht, dass der Fluss zur Kontolöschung nicht wichtig war. Es bedeutet nur, dass die Leute ihn nicht in jeder Sitzung aufrufen.

Dan Abramov, Twitter

Das ist es, was mich zusätzlich beunruhigt: alert() ist eine Sache, aber confirm() gibt buchstäblich true oder false zurück, was bedeutet, dass es eine logische Kontrollstruktur in einem Programm ist. Die Entfernung davon bricht Websites, keine Frage. Chris Ferdinandi hat mir diese kleine obskure Website gezeigt, die es verwendet.

Wo wir gerade von Chris sprechen

Das herablassende „hast du es wirklich gelesen, es ist so klar“ ist patronisierend AF. Es ist das Äquivalent von „nur“ oder „einfach“ in der Entwicklerdokumentation.

Ich habe es gelesen. Ich habe es nicht verstanden. Deshalb habe ich jemanden gefragt, dessen Aufgabe es buchstäblich ist, mit Entwicklern über Änderungen zu kommunizieren, die Chrome an der Plattform vornimmt.

Dies ist nicht auf einen Entwickler bei Chrome beschränkt. Der gesamte Nachrichtenthread, in dem diese Änderung aufgetaucht ist, ist voller Leute, die Chrome bitten, diesen Vorschlag nicht weiterzuverfolgen, da er alles kaputt machen wird.

Chris Ferdinandi, „Google vs. the web“

Und hier ist Jeremy

[…] brechende Änderungen passieren auf dem Web nicht oft. Sie sind – und sollten sein – selten. Wenn sich das ändern würde, würde das Web massiv unter der Vorhersagbarkeit leiden.

Zweitens liegt die Verantwortung nicht bei den Webentwicklern, ältere Funktionen im Auge zu behalten, die von der Abschaffung bedroht sind. Das liegt bei den Browserherstellern. Ich hoffe aufrichtig, dass von uns nicht erwartet wird, dass wir eine Seite namens canistilluse.com konsultieren.

Jeremy Keith, „Foundations“

Ich habe hier ein ziemlich düsteres Bild gezeichnet. Um fair zu sein, gab es einige Tweets mit der Stimmung Ja!! Endlich!!, aber sie fühlten sich für mich nicht wie kritische Einschätzungen an, sondern eher wie zufälliges Google-Jubel.

Ob Sie es glauben oder nicht, ich bin im Allgemeinen ein Fan von Google und denke, dass sie gute Arbeit leisten, das Web voranzutreiben. Ich denke auch, dass es angebracht ist, mit dem Finger zu zeigen, wenn ich Probleme sehe und sie bitte, sich zu verbessern. „Besser“ bedeutet hier viel mehr Entwickler- und Nutzer-Outreach, um die Situation zu erläutern, viel mehr Gespräche über die potenziellen Auswirkungen und Übergangsideen und viel mehr Offenheit, den Kurs zu ändern.