OOP in JavaScript. Oder: Wenn ich nochmal "this is undefined" lese, schreie ich!

Ich verwende IE 11. Und zumindest den “experimental-webgl” Kontext hat er erzeugt. Aber XMLHttpRequest motzt über “Unhandled rejection Error: Zugriff verweigert” beim Versuch, das JSON aus einer lokalen Datei zu lesen.

Hört sich nach einem sehr interessanten Problem an. Wenn ich Zeit habe, würde ich es mir gerne anschauen.

Wenn man das verlinkte Ding auspackt und direkt die HTML im IE aufmacht, sollte das “Access Denied” schon in der Konsole erscheinen. Websuchen liefern natürlich etliches, aber eben als beunruhigend ungeordneter Strudel von Schnipseln, Bugreports, “Im IE6 ging das so-und-so”-Blog Posts usw. Ich bin mir nicht sicher, wie viel Zeit mit mühsamem Frickeln und Rumprobieren ich für irgendeine verkackte Browser-Inkompatibilität aufwenden will, aber … weniger, als ich schon getan habe.

Eine Datei lesen.

Hm.

Ich habe mal versucht es in Chrome zu starten, geht irgendwie nicht. Auch scheint es mit IE generell nicht zu funktionieren, da ich versucht habe die HTML über den eingebetten Python-Server im Ordner zu starten. (Zeigt nur eine Art Stopknopf an, ist vermutlich vom Debugger)(Startbefehl des Python-Servers: python -mhttp.server). Aber dafür dürfte zumindest das XMLHttpRequest Problem gelöst zu sein, da sich dein beschriebener Fehler nicht anzeigt.

Hab’ gerade mal den Chrome Portable runtergeladen, und der sagt da das gleiche, aber mit dem ausführlicheren Hinweis: “Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.”

Auch wenn ich mir selbst schon wie ein stures, quengelndes Kleinkind vorkomme: Ich will eine Datei lesen. Und ich will diese Datei lesen, ohne einen Webserver laufen lassen zu müssen. Mal im Ernst, was soll DAS denn sein? :sick: (Zu JSONP: Es geht auch um Text- und Binärdateien, aber mit der JSON fängt’s halt an…). WAS ist denn WO falsch gelaufen, dass da ein derart unbrauchbarer Mist rausgekommen ist?!

Binäres könnte man ja über einen Base64 String übertragen. Plain mit einem normalen String.
JSON:
[JavaScript]“dies hier ist auch gültiges JSON nach rfc7159”[/JavaScript]
Das dazugehörige JSONP
[JavaScript]whateverFunc(“dies hier ist auch gültiges JSON nach rfc7159”);[/JavaScript]

Binär ist binär. Das ist eine Datei auf der Festplatte. Die kann ich nicht ändern.

Mit zwei kleinen Änderungen geht’s mit einem eigenen Server in Chrome, aber der IE weigert sich auch dann noch,

  1. JSON als solches zu lesen (kann aber notfalls mit JSON.parse zurechtgehackt werden)
  2. Binardaten aka einen arraybuffer zu lesen (da hab’ ich jetzt keinen Bock mehr, weiter rumzuprobieren)

Also ich versteh die Aufregung hier echt nicht, @Marco13 . Wenn ich das richtig verstanden hab, willst du mit einem Javascript, welches innerhalb eines HTML Dokuments laeuft, auf die Festplatte zugreifen?

Wie du schon richtig geschrieben hast, geht das grundsaetzlich erstmal nicht. Und das ist gut so, sonst koennte dir jedes Script mal eben den .ssh Ordner irgendwo hin schicken. Oder auch dein Userhome loeschen. Deshalb: Das funktioniert einfach nicht. Klar, gibt bestimmt irgendwelche kruden Hacks oder Plugins fuer den Browser - aber das ist doch nicht sinnvoll. Wieso willst du sowas machen?

Was require.js und Abhaengigkeitsmanagement angeht, da muss man sich schon mal etwas mit beschaeftigen. Stichworte waere z.B. Grunt, npm oder package.json. Laeuft am Ende auf ne halbwegs sinnvolle Projektstruktur hinaus, wobei ein mehr oder weniger normales Buildtool am Ende ein fertig verpacktes und evtl. geminifytes JS File ausspuckt.

Wenn dich die Prototypstruktur wie in deinem ersten Post nervt, nimm ES6 im strict mode. Dann hast du ziemlich normal aussehende Klassen, wie man sie von Java kennt.
Wenn dich die Syntax von JS nervt, nimm einen Transpiler, wie z.b. Coffeescript - da biste immer noch im ganz normalen Javascript Context, nur hast eine bisschen andere Syntax.
Willst du dich nicht auf die Javascriptwelt einlassen, nimm z.B. Kotlin und waehl als Compiletarget Javascript. Da kannst mehr oder weniger normal coden, gradle oder maven benutzen und hast am Ende auch ein einziges JS File, zum Einbinden ins HTML.

Und ja, Javascript ist Murks. Wissen alle. Geht aber (wenn man sich ins Thema gewuehlt hat) fast ueberall und auf jedem Geraet.

[QUOTE=schalentier]Also ich versteh die Aufregung hier echt nicht, @Marco13 . Wenn ich das richtig verstanden hab, willst du mit einem Javascript, welches innerhalb eines HTML Dokuments laeuft, auf die Festplatte zugreifen?

Wie du schon richtig geschrieben hast, geht das grundsaetzlich erstmal nicht. Und das ist gut so, sonst koennte dir jedes Script mal eben den .ssh Ordner irgendwo hin schicken. Oder auch dein Userhome loeschen. Deshalb: Das funktioniert einfach nicht.
[/QUOTE]

Ich will auf MEINEM Rechner mit MEINEM Script MEINE Datei von MEINER Festplatte lesen (meinetwegen mit gezogenem Netzwerkkabel). Sandbox und Sicherheitsmechanismen hin oder her: Wenn das nicht geht, ist das himmelschreiender Murks. Natürlich, wenn ich auf illegal-warez.ru gehe, soll diese Seite nicht auf meine Dateien zugreifen können (und genaugenommen überschreiten schon viel „harmlosere“ Formen des Scriptings auf Webseiten in meinen Augen die Grenze zum Hausfriedensbruch - NoScript ist installiert). Aber das sollte doch spätestens darin seine Grenze finden, dass es möglich sein sollte, mit einem LOKALEN (!) Script C:\myScript.js auf die LOKALE Datei C:\file.json zuzugreifen. Meinetwegen auch mit irgendeiner Abfrage „Wollen sie den Zugriff zulassen?“, oder der Notwendigkeit den Browser mit einem -IknowWhatImDoing-Parameter zu starten. Aber dass die gesamte Infrastruktur auf das Unmöglichmachen eines der elementarsten Dinge ausgerichtet ist, die man mit einem Computer überhaupt machen kann (selbst eine Turingmaschine liest Daten :rolleyes: ), dass also „„die ‚Sprache‘ als solche““ das verbietet, KANN man mit kaum mehr als Kopfschütteln kommentieren.

Ich habe zwar schon angefangen, mich in require.js reinzufräsen, aber meine Skepsis dazu hatte ich ja auch schon erwähnt. Ansonsten … ja, ES6 im IE11, sicher… mit irgendeinem ES6-Script, den man mit require.js einbindet (oder doch mit script-tag? Und was ist eigentlich ein polyfill? (Ich will es eigentlich nicht wissen, werde es aber doch lesen)). Aber mal einen Tick sachlicher: Die Prototypstruktur aus dem ersten Post KÖNNTE ja OK sein. Wenn sie nicht in der „verbesserten“ Version komplett anders wäre, und man davon ausgehen muss, dass man, wenn man drei Leute fragt, was sie davon halten, vier Antworten bekommt, wie man „das alles besser“ machen könnte (und die wiederum nichts gemeinsam hätten).

Ja, ich weiß, Alternativen gibt es reichlich, aber am Ende ist es doch JavaScript. Die Syntax ist gewöhnungsbedürftig, aber da fräst man sich halt rein, und dann kann das auch OK sein, SOFERN es überhaupt die Möglichkeit gibt, irgendwas „gut“ oder „idiomatisch“ zu lösen. Die gibt es aber, wie schon angedeutet, anscheinend nicht: Für jedes Problem gibt es 3 Lösungen, die komplett unterschiedlich sind, und alle „schlecht“ in dem Sinne, dass hier oder da nicht funktionieren, oder sie irgendwelche absurden Seiteneffekte eines nicht-vorhandenen Typsystems ausnutzen. Man sieht dann sowas wie JavaScript function declaration syntax: var fn = function() {} vs function fn() {} - Stack Overflow mit 4300 upvotes (was schon viel aussagt), eine akzeptierte Antwort mit 3300 Upvotes, und eine weitere Antwort mit 1400 upvotes, die erstmal sagt, das die erste Antwort „„falsch““ ist. Ich bin ja eigentlich „fleißig“ und bereit, mich auf bestimmte Dinge einzulassen. Und ich würde ja sogar die relevanten Teile der 3000 Seiten auf ECMAScript 2015 Language Specification – ECMA-262 6th Edition lesen. Wenn ich nicht wüßte, dass das für die Tonne ist, denn…

… das stimmt nicht. Es gibt offenbar kein nicht-triviales Programm, das nicht irgendwas macht, was in irgendeiner Hinsicht „schlecht“ ist, und was auf irgendeinem Browser nicht funktioniert. Ja, dass ich z.B. Object.entries() - JavaScript | MDN verwendet hatte, kann man mit „selbst schuld“ kommentieren, aber darüber hinaus scheint jeder Browser zu machen, was er will.
Vielleicht täuscht das alles aber auch gerade…

Dein Ansatz ist falsch. Wenn du einfach nur ein File lesen willst, musst du Node.JS nehmen. Das ist im Endeffekt sowas wie das JDK+JVM fuer Javascript. Das was im Browser laeuft ist dann eher ein Applet (hies doch so, oder), was eine kastriertes JDK in einer gesandboxten JVM laufen laesst.

Eben genau aus dem Grunde, dass es mit einem modernen Browser einfach unmoeglich sein sollte, irgendwas auf dem lokalen System zu lesen oder zu veraendern. Nicht mit einer Abfrage, die 99% der DAU IMMER mit Okay bestaetigen.

Das geht schon, wie gesagt, dafuer ist Grunt da - kannst auch noch irgendwelche Tools ueber dein finales JS Artefakt laufen lassen, die Fehler finden oder spezielle Versionen fuer spezielle Browser bauen. Am Ende hast du ein einziges JS (evtl. halt eins pro Browser), was du in dein HTML einbindest. Ich versteh dein Problem hier nicht.

Schau dir doch mal Kotlin an - da hast du Typen ganz normal wie in Java auch, eine kleine Standardlib fuer ueblichen Krimskrams und kann ziemlich einfach auch Fremdlibraries einbinden.

Oder: Warum muehst du dich ueberhaupt mit JS ab, wenn es doch soooooo Scheisse is? Einfach nicht nehmen, ignorieren und fertig?

Ja, das versteht nie jemand. Ist wohl auch nicht so wichtig.

Ich verstehe das Problem bestens. Bei JavaScript gibt es so viele verschiedene Tools und Frameworks, dass man anfangs etwas überwältigt ist. Eigentlich will Marco bloß eine Datei einlesen, da wird einem aber irgendwas mit Grunt, Babel, Node, npm und Typescript erzählt. Bei Java hat man eine JDK, sodass man sich prinzipiell nicht darum kümmern muss, auf unterschiedliche Umgebungen zu achten. Bei der Webentwicklung funktioniert das einfach nicht, wenn man 4-5 große Browser hat, die größtenteils keine einheitliche Spezifikation haben oder bloß einige Features noch nicht umgesetzt haben. Und dann kommt noch die Abwärtskompatibilität hinzu.

Es gibt für dein Problem mehrere Lösungen:

  1. Node.js verwenden, wenn du eine Datei einlesen und etwas damit anstellen (also ein Kommandotool entwickeln) möchtest.

  2. Ein Build-System verwenden, das deine Dateien zu einer JS-Datei zusammenführt, falls es am Ende doch im Browser ausgeführt werden soll.

  3. Alle JS-Dateien in der Host-HTML-Seite einbinden:

<script src="datei1.js">
<script src="datei2.js"> 
  1. Falls es keine JS-Datei ist, die du einbinden möchtest - über einen AJAX-Aufruf geht auch das. Ich habe dafür jQuery genommen, es geht aber sicherlich auch mit reinem JavaScript. Wenn die Datei lokal ist, kommen dennoch ein paar Schwierigkeiten auf dich zu.

wurde schon genannt warum diese Aufgabe, die anscheinend für zivilisierte Sprachen wie Java geeignet ist, in JavaScript sein muss? :wink:

Also ganz ehrlich, ich find diese Argumentation wirklich absurd. Bei Java gibts nur genau einen Weg? Keine Tausend Tools? Genau ein Framework? o.O

Ich koennt jetzt auch meckern, wie furchtbar kompliziert die Anbindung eines Hardwaretreibers fuer z.B. einen speziellen DSP Soundchip ist. JNDI, DLL’s und am Ende ist es auch nicht kompatibel und funktioniert nicht unter Linux. Java is ja soooo kacke.

Ein Browser DARF keinen Zugriff auf die lokale Festplatte haben. Punkt!

Mir will einfach nicht in den Kopf, wieso sich Leute immer wieder ueber bestimmte Technologien aufregen und meckern, obwohl sie diese ueberhaupt nicht verstanden haben (Javascript ist da nur ein Thema, gleiches gilt fuer Ruby, fuer React und fuer viele andre Sachen). Man sollte an neue unbekannte Technologien immer „Open Minded“ rangehen und nicht von Anfang an alles nur schwachsinnig finden.

Du meinst Entscheidungen, wie Guava oder Apache Commons? Wie Maven vs. Gradle? JUnit oder TestNG? Das ist nix gegen das JS-Ökosystem, bei dem täglich neue Frameworks entstehen, weil die Autoren mit den bisherigen Lösungen unzufrieden sind. Wenn ich nur das Testframework als Beispiel nehme. So gut wie jeder verwendet JUnit in Java. In JavaScript hast du eine Menge von Testframeworks, und zusätlich eine Menge von Assert-Libraries, mit keinem klaren Gewinner, wie das bei JUnit der Fall ist. Nicht falsch verstehen - ich finde diese Vielfalt in JS toll und im Gegensatz zu den meisten anderen Java-Entwicklern mag ich JavaScript wirklich, aber bei der Einarbeitung fängt der Kopf nun mal an zu rauchen. Und dann kommt die unglaublich „coole“ JS-Community, welche dir klarmachen möchte, dass Framework X kacke ist und du lieber Framework Y einsetzen solltest (zumindest diese Woche). Dann gibt es Artikel, wie State of the Art Javascript in 2016, welche versuchen den aktuellen Trend zu erfassen.

Ich würde einen Schritt weiter gehen: es gibt keinen vernünftigen Grund, warum ein Browser überhaupt Zugriff auf die Festplatte haben sollte.

Anbindung eines Hardwaretreibers ist ein denkbar ungünstiges Beispiel,
dass sich eine Sprache spät in verschiedene Frameworks aufteilt ist normal

das entscheidende Wort mag hier ‚anfangs etwas überwältigt‘ sein,
die Java-API reicht zum Einstieg und auch später sehr sehr lange,

es ist nicht alles optimal darin, aber viel brauchbares vorhanden mit jeder Menge Beispiele,
Datei lesen oder schreiben (mehrere funktioniere Wege ohne Installation zur Auswahl vorhanden nicht schlimm!), Benutzereingaben von Konsole,
ganze mächtige GUIs zusammenbauen, Bilder einbinden oder auch pixelgenau einzeln malen,
Collections, Date, Rechnen, Random,
man muss schon etwas suchen was man damit in den ersten Jahren nicht alles von allein schaffen kann

ok, DB-Anschluss, Logging, XML/ CSV usw., aber ist dann auch teils Anschluss externer Komponenten und langsam individuelle Themen

über Swing meckern manche, man darf ja ruhig später anderes verwenden,
aber wie viele haben damit die ersten Schritte in GUI gelernt und können sich freuen dass auch hier im Forum praktisch jeder helfen kannt ( setVisible(true) nach hinten! ),
sowas ist sehr sehr wertvoll


Dateiupload Email? :wink:
ein Browser ist schon eine tolle Sache als plattformübergreifende leichtgewichtige überall vorhandene mögliche GUI für Programme,
siehe Erfolg der Browser-Spiele, Büroanwendungen genauso und auch schon zunehmend, schätze ich,

dass dabei Dateizugriff ein wünschenswertes Feature sein kann, falls nicht alles ‚in der Cloud‘, versteht sich von selbst

Geht doch beides ohne JS, ganz klassisch über HTML Forms mit einem PHP-Skript dahinter.

was wäre hier ‚beides‘, auch die Email ein Punkt?
Email oder hier im Forum schreiben ist ja noch Input von Tastatur, Dateiupload dazu eine Funktion, die doch irgendwie auf die Festplatte zugreifen muss,

bei der Aussage

war nur JS gemeint, anderes ok?

gut, freilich auch etwas Unterschied dahinter, das eine verschickt, evtl. an lokalen Server, das andere will selber direkt zugreifen…

Ja gut, ich meinte schon JS. Aber genauer ging’s mir darum, dass eine Website keine Möglichkeit haben sollte, selbstständig auf irgendwelche Dateien von mir zuzugreifen. Wenn ich eine Datei freiwillig auswähle, ist das natürlich was anderes (wobei ich mir vorstellen kann, dass auch das früher zu kreativen Sicherheitslücken geführt hat).

„Zivilisiert“ trifft es wohl ganz gut. Der Browser, der unter Release jgltf-browser preview release 3 · javagl/JglTF · GitHub rumflackt, kann etwas mehr, als das JS jetzt können soll. Das Ziel hier war eigentlich einen (oder sogar DEN) minimalst-möglichen glTF-Viewer in JS zu schreiben. Warum? Ach, frag’ doch nicht SOwas :rolleyes: :wink:

[QUOTE=darekkay;138939]

  1. Node.js verwenden, wenn du eine Datei einlesen und etwas damit anstellen (also ein Kommandotool entwickeln) möchtest.

  2. Ein Build-System verwenden, das deine Dateien zu einer JS-Datei zusammenführt, falls es am Ende doch im Browser ausgeführt werden soll.

  3. Alle JS-Dateien in der Host-HTML-Seite einbinden:

<script src="datei1.js">
<script src="datei2.js"> 
  1. Falls es keine JS-Datei ist, die du einbinden möchtest - über einen AJAX-Aufruf geht auch das. Ich habe dafür jQuery genommen, es geht aber sicherlich auch mit reinem JavaScript. Wenn die Datei lokal ist, kommen dennoch ein paar Schwierigkeiten auf dich zu.[/QUOTE]

  2. Es soll schon in einem Browser sein. Ein glTF-Viewer, der an der Konsole läuft, würde den Nagel nicht so ganz auf den Kopf treffen.

  3. Ohne da den Überblick zu haben, will/wollte ich vermeiden, Arbeit an Infrastrukturen zu delegieren, die mit meinem Code dann „irgendwas“ machen, und wo jede Fehlermeldung im Browser dann nur sagt, dass in einer Zeile wie requirejs/require.js at master · requirejs/requirejs · GitHub irgendwas „undefined“ ist, und keine Möglichkeit mehr besteht, die Ursache zu erkennen. Auch in Anlehnung an…

3.: So hatte ich es zuerst sehr lange. Dann habe ich versucht, das ganze auf IE zu starten. Wie, „Promise is undefined“? Ach so, ES6-Script (welches? Bluebird, oder irgendwas anderes?) und das dann einbinden (Wie, per ? Aber was ist ein „polyfill“, und überschreibt das dann nicht alles auch im FF?) Am besten sollte das nur auf dem IE eingebunden werden (geht angeblich, praktisch dann aber doch nicht), und was braucht man sonst noch? Ancheinend kommt man um Require.js eben nicht drumrum…

  1. Auch dieser Link war schon Lila. Ein Problem IST ja, dass man 1000 Seiten findet, auf denen größtenteils Müll steht, oder hemdsärmelige Begründungen, warum es nicht funktioniert. Dass man viele dieser Probleme mit einem eigenen Webserver umgehen könnte, weiß ich, aber das finde ich, ganz subjektiv und aus den schon genannten (aber zugegeben, etwas in den Rants versteckten) Gründen einfach nur haarsträubend.

Meine „Roadmap“ ist jetzt, dass diese Dateien dann in Zukunft halt nicht mehr direkt geladen werden, sondern Per Drag&Drop. Was ja vieeel sicherer ist :rolleyes: In der obersten JSON stehen Links auf Binärdateien, die dann wahrscheinlich nicht geladen werden können (weil sie ja nicht gedraggt&droppt wurden :rolleyes: :sick: ), aber notfalls kriegt der Benutzer dann halt eine Liste angezeigt: „Please drag and drop these 56 files into your browser window, one by one: …“ :rolleyes:

EDIT: Noch ein Nachtrag zur etwas allgemeineren Diskussion: Sicher, auch in Java gibt es Frameworks usw. Und beim oben Verlinkten Viewer stand ich vor der Frage „LWJGL oder JOGL?“, und habe mit einer krampfig-hemdsärmeligen Abstraktion diese Frage dann mit „Beides“ beantwortet. Der dramatische (und für diesen Thread relevante) Unterschied ist, dass man in Java rein „syntaktisch“ eine Klasse genau auf eine Art schreiben kann. Und man kann eine Datei auf kaum mehr als eine Art laden. Und man kann dependencies nur auf eine Art behandeln (classpath, dass Maven das versteckt spielt keine Rolle). Aber bei JavaScript gibt es NICHTS verbindliches. Es gibt schon X vollkommen verschiedene Arten, eine „funktion“ zu definieren, von einer „Klasse“ ganz zu schweigen. Dass man Dateien nicht lesen kann (aber es 10 verschiedene Arten gibt, „Irgendwas irgendwo her zu lesen“ (und keine davon immer und richtig funktioniert)) wurde ja schon ausgewalzt. Und nochmal die Frage: Was ist „require.js“? Das ist irgendeine Library, die irgendein Honk zusammengeschustert hat. Da ist nichts standardisiert, nichts spezifiziert, nichts verbindlich. Es kann doch nicht sein, dass in der 3000-Seiten-Spec nicht drinsteht, wie ein Projekt aus ZWEI Dateien zusammengebaut wird…?!