Bachsau: Javascript "escape" wird durch "encodeURI" ersetzt?

Habe ich gerade im SelfHTML gelesen:

"Beachten Sie: Diese Funktion wird in Zukunft durch  encodeURI() ersetzt!"

Hallo gehts noch? Das ist doch etwas völlig anderes, die Funktion hat schon ihren Zweck, denn sie ermöglich eine URI als parameter einer anderen URI zu sehen, ohne dass die angaben übernommen werden:

if(parent==self) top.location.replace("/?uri="+escape(self.location.href));

Das ist eine einfach "Bau dich in ein Frameset ein"-Funktion. Würde an dieser stelle encodeURI eingesetzt würde das doch total falsch.

Gruß
Bachsau

  1. Hallo Bachsau.

    Habe ich gerade im SelfHTML gelesen:

    "Beachten Sie: Diese Funktion wird in Zukunft durch  encodeURI() ersetzt!"

    Hallo gehts noch?

    Immer mit der Ruhe.

    Einen schönen Sonntag noch.

    Gruß, Mathias

    --
    ie:% fl:| br:< va:) ls:& fo:) rl:( n4:~ ss:) de:] js:| mo:| zu:)
    debian/rules
    1. Hi, hab ich mal durchgelesen b.z.w. überflogen. Allerdings ändert das immer noch nichts dran, dass der Befehl manchmal notwendig ist. Weil es eben manchmal notwendig ist, strings nach UTF-8 zu kodieren. Auch wenn sich das für formulare vielleicht nur bedingt oder garnicht eignet, dann eben wie ich es auch beschrieben habe, für was anders.

      So heißen, wenn die Funktion rausfliegt währe JavaScript tatsächlich um eine nützliche Funktion ärmer, zumal eine unterstützung dessen kein Brot frisst. Oder seh ich das falsch? ;)

      Gruß
      Bachsau

      1. Weil es eben manchmal notwendig ist, strings nach UTF-8 zu kodieren. Auch wenn sich das für formulare vielleicht nur bedingt oder garnicht eignet, dann eben wie ich es auch beschrieben habe, für was anders.

        Irgendwie hast du nicht verstanden worum es bei escape() geht, das hat nichts mit utf-8 zu tun und für Fomrulare brauchst du es erst recht nicht, da der Browser die URL Kodierung dort von alleine durchführt.

        Struppi.

        1. Hallo Struppi,

          für Fomrulare brauchst du es erst recht nicht, da der Browser die URL Kodierung dort von alleine durchführt.

          Ich habe die Diskussion mal ein wenig verfolgt und auch die von Mathias verlinkten Thread durchgelesen. Indirekt habe ich das selbe Problem wie der Fragestellende. Wobei ich mir hier eher wenig Gedanken gemcht habe und einfach das genommen habe, was letztlich funktioniert.

          Ich erlaube dem User das Eingeben eines Ortes und gestalte dann eine Abfrage mit JS dieses Ortes in einer DB, um die Koordinaten zu bekommen. Probleme waren zunächst Orte mit Umlauten (zB Köln) oder Leerzeichen (jede Dadstadt). Mache ich mit den Formulardaten nicht, übergebe sie also so, wie sie mit JS aus dem Textfeld ausgelesen werden, passiert nichts. Nutze ich encodeURI() erziele ich das selbe Ergebnis. Erst mit dem Einsatz von escape() gehts - Städte mit Umlauten werden gefunden.

          Wie geht man denn nun vor; gerade auch wegen dem mahnenden Hinweis von molily, "Warum du auf keinen Fall escape() verwenden solltest" beachtet?

          Derzeit mache ich es wie gesagt mit escape():

            
          function Query(k, v){  
           this.key = k.trim();  
           this.value = escape(v.trim()); //encodeURI(), escape()  
           //...  
          }
          

          Mit freundlichem Gruß
          Micha

          1. Ich erlaube dem User das Eingeben eines Ortes und gestalte dann eine Abfrage mit JS dieses Ortes in einer DB, um die Koordinaten zu bekommen.

            Was heißt Abfrage mit JS? AJAX?
            Dann treten Probleme auf, wenn die Kodierung des Response, der darstellenden Seite und der Kodierung bzw. Dekodierung nicht identisch sind. Letztlich ist es am sinnvollsten alles in utf-8 zu machen, dann brauchst du encodeURI()

            Derzeit mache

            Der Zeichensatz der Seite ist ISO-ISO-8859-1, deshalb brauchst du escape(), wenn der Response des XMLHttpRequest auch in ISO-8859-1

            Struppi.

            1. Hallo Struppi,

              vielen Dank für Deine Antwort!

              Was heißt Abfrage mit JS? AJAX?

              Ja, mit dem XMLHttpRequest-Objekt.

              Dann treten Probleme auf, wenn die Kodierung [...] nicht identisch sind. Letztlich ist es am sinnvollsten alles in utf-8 zu machen, dann brauchst du encodeURI()

              Wiederspricht Dein erste Satz nicht dem zweiten? Ich hätte gefolgert, dass lediglich auf einheitliche Kodierung zu achten ist, um Probleme zu vermeiden - unabhängig davon, für was ich mich entscheide.

              Der Zeichensatz der Seite ist ISO-ISO-8859-1, deshalb brauchst du escape(), wenn der Response des XMLHttpRequest auch in ISO-8859-1

              Ja ist es bzw. habe ich erzwungen: header('Content-Type: text/plain; charset=ISO-8859-1');.

              Mit freundlichem Gruß
              Micha

          2. Moin!

            Ich erlaube dem User das Eingeben eines Ortes und gestalte dann eine Abfrage mit JS dieses Ortes in einer DB, um die Koordinaten zu bekommen. Probleme waren zunächst Orte mit Umlauten (zB Köln) oder Leerzeichen (jede Dadstadt). Mache ich mit den Formulardaten nicht, übergebe sie also so, wie sie mit JS aus dem Textfeld ausgelesen werden, passiert nichts. Nutze ich encodeURI() erziele ich das selbe Ergebnis. Erst mit dem Einsatz von escape() gehts - Städte mit Umlauten werden gefunden.

            encodeURI() codiert gewisse Zeichen nicht, die man aber codieren muß, wenn diese Zeichen als Nutzdaten z.B. im Parameterteil der URL vorkommen sollen.

            Deshalb gibt es encodeURIComponent(), welches genau diese Zeichen (u.a. das Leerzeichen) noch zusätzlich codieren.

            Sprich: encodeURI() ist eigentlich nur dann nützlich, wenn man einen URI-Teil _vor_ dem Fragezeichen bearbeiten will. Geht's hingegen um irgendwas _hinter_ dem Fragezeichen, was man aus eigenen Einzelteilen zusammensetzen möchte, ist encodeURIComponent() richtig.

            - Sven Rautenberg

            --
            "Love your nation - respect the others."
            1. Hallo Sven Rautenberg,

              Geht's hingegen um irgendwas _hinter_ dem Fragezeichen, was man aus eigenen Einzelteilen zusammensetzen möchte, ist encodeURIComponent() richtig.

              Ich hätte es schreiben sollen; auch das hatte ich versucht und lieferte kein Ergebnis bei der Abfrage mit Orten, die Umlaute oder Leerzeichen enthielten. Von den Dreien (encodeURI(), escape(), encodeURIComponent()) funktioniert die Abfrage nur mit escape.

              Mit freundlichem Gruß
              Micha

              1. Moin!

                Geht's hingegen um irgendwas _hinter_ dem Fragezeichen, was man aus eigenen Einzelteilen zusammensetzen möchte, ist encodeURIComponent() richtig.

                Ich hätte es schreiben sollen; auch das hatte ich versucht und lieferte kein Ergebnis bei der Abfrage mit Orten, die Umlaute oder Leerzeichen enthielten. Von den Dreien (encodeURI(), escape(), encodeURIComponent()) funktioniert die Abfrage nur mit escape.

                Das liegt dann aber an deinem Backend, welches einfach ignoriert, dass AJAX nun mal nur mit UTF-8 arbeiten kann. Wenn du im Backend mit ISO-8859-1 arbeitest, mußt du die reinkommenden Daten logischerweise umcodieren.

                Escape klappt deshalb, weil es auf ISO-8859-1-Basis codiert, d.h. ein deutscher Umlaut erhält dort die %XY-Hexdarstellung aus dem ISO-Zeichensatz - was PHP wiederum zurückführt auf den wirklichen Umlaut.

                encodeURIComponent() codiert den Umlaut auf Basis von UTF-8 als zwei Bytes (%XY%YY), was PHP im ISO-8859-1-Kontext dann nicht mehr als Umlaut erkennen kann - und dein Backend logischerweise auch nicht.

                Mit utf8_decode() würd's aber wieder gehen.

                - Sven Rautenberg

                --
                "Love your nation - respect the others."
                1. Lieber Sven,

                  Mit utf8_decode() würd's aber wieder gehen.

                  Das war das, was mir wohl fehlte! ich hatte es nur kurz mit urldecode in einer Kombination proboert - ohne Erfolg...

                  Ich habe nun drei Sachen geändert. Die JS Anfrage kodiere ich, wie Du es vorgeschlagen hast, mit encodeURIComponent. Im PHP-Script kodiere ich "zurück": utf8_decode( ... ) und die Ausgabe des PHP-Scripts kodiere ich wiederum mit utf8-encode() und "übergebe" sie dem JS (responseText). Muss ich dann eigentlich wieder decodieren? ;-)

                  Escape klappt deshalb, weil es auf ISO-8859-1-Basis codiert, d.h. ein deutscher Umlaut erhält dort die %XY-Hexdarstellung aus dem ISO-Zeichensatz - was PHP wiederum zurückführt auf den wirklichen Umlaut.

                  Ist das nicht gerade der Vorteil schlecht hin? Stell ich an das PHP-Script nun direkt eine Anfrage (?orte=<ortsname>), funktioniert diese zwar mit Opera aber im FF nicht. Opera macht bspw aus köln k%C3%B6ln (das ist nach Deiner Beschreibung ja utf-8); Firefox lediglich k%F6ln (das ist dann wohl ISO-8859-1-Basis). Dies wird sicher an meinen jeweiligen Browsereinstellungen liegen, führt aber in einem Fall zu einem Ergebnis im anderen nicht und das ist ja eher unerwünscht. Kann ich die Codierung der Parameter erkennen und entsprechend handeln? Oder habe ich irgendwo was mißverstanden?

                  Mit freundlichem Gruß
                  Micha

                  1. Moin!

                    Lieber Sven,

                    Mit utf8_decode() würd's aber wieder gehen.
                    Das war das, was mir wohl fehlte! ich hatte es nur kurz mit urldecode in einer Kombination proboert - ohne Erfolg...

                    Ich habe nun drei Sachen geändert. Die JS Anfrage kodiere ich, wie Du es vorgeschlagen hast, mit encodeURIComponent. Im PHP-Script kodiere ich "zurück": utf8_decode( ... ) und die Ausgabe des PHP-Scripts kodiere ich wiederum mit utf8-encode() und "übergebe" sie dem JS (responseText). Muss ich dann eigentlich wieder decodieren? ;-)

                    HTML und Javascript arbeiten standardmäßig intern sowieso mit dem gesamten Unicode-Zeichenbereich. An den Schnittstellen zur Außenwelt (also Requests vom Server) wird durch das HTTP-Protokoll, ersatzweise auch durch ein Meta-Tag (wobei es das nicht in allen "Sprachen" gibt), mitgeteilt, wie die übermittelten Bytes zu verstehen sind, und direkt vom Browser in das interne Unicode-Format gewandelt.

                    Insofern: Wenn du UTF-8 sendest und das dem Browser mitteilst, dann weiß er alles, was er wissen muß.

                    Escape klappt deshalb, weil es auf ISO-8859-1-Basis codiert, d.h. ein deutscher Umlaut erhält dort die %XY-Hexdarstellung aus dem ISO-Zeichensatz - was PHP wiederum zurückführt auf den wirklichen Umlaut.
                    Ist das nicht gerade der Vorteil schlecht hin? Stell ich an das PHP-Script nun direkt eine Anfrage (?orte=<ortsname>), funktioniert diese zwar mit Opera aber im FF nicht. Opera macht bspw aus köln k%C3%B6ln (das ist nach Deiner Beschreibung ja utf-8); Firefox lediglich k%F6ln (das ist dann wohl ISO-8859-1-Basis). Dies wird sicher an meinen jeweiligen Browsereinstellungen liegen, führt aber in einem Fall zu einem Ergebnis im anderen nicht und das ist ja eher unerwünscht. Kann ich die Codierung der Parameter erkennen und entsprechend handeln? Oder habe ich irgendwo was mißverstanden?

                    ISO-8859-1 ist kein Vorteil. Im Gegenteil wird es immer mehr zum Nachteil, denn damit kannst du ja nur 256 verschiedene Zeichen codieren. Das sind zwar fast alle, die im westeuropäischen Kulturkreis benutzt werden - aber das muß ja nicht zwingend ausreichen. Es scheitert schon beim Eurozeichen, was in ISO-8859-1 nicht codiert werden kann, weil's dort schlicht nicht enthalten ist.

                    Es gibt auch angesichts der in der Realität auftauchenden Browser keinen Grund mehr, nicht UTF-8 einzusetzen. Die Unterstützung dafür wird immer besser, auch in den diversen Open-Source-Produkten.

                    - Sven Rautenberg

                    --
                    "Love your nation - respect the others."
                    1. Hallo Sven Rautenberg,

                      okay, das ändert doch aber nichts daran, das mein Firefox (scheinbar) die URL nicht in utf-8 kodiert - oder war dies ein wink mit dem sprichwörtlichen Zaunpfahl, ich solle es umstellen?
                      Die Frage hat zwar nichts mehr mit meinem eigentlichen Problem zu tun, da es dort geht, aber wenn ich das PHP-Schript direkt aufrufe, hätte ich wieder ein Problem:

                      http://dev.derletztekick.de/usermap/locals.php?orte=berlin

                      versuch Berlin durch Köln, München oder der gleichen zu ersetzen, dann wird es - bei gleichen Einstellungen - im FF nicht gehen. Wie umgeht man diesen Umstand? Wenn ich den Parameter selbst anfügt zB in einem Link, kann ich es korrekt kodieren - klar. Nur, wenn der User den Parameter ändert (in der URL), habe ich ja erstmal keinen Einfluß drauf. Mach ich mir hier in die falsche Richtung Gedanken?

                      Mit freundlichem Gruß
                      Micha

                      1. Hallo,

                        Wenn ich den Parameter selbst anfügt zB in einem Link, kann ich es korrekt kodieren - klar.

                        Ja, wenn du die URI selbst zusammenbaust oder es sich um ein GET-Formular handelt, kannst du die Kodierung einfach bestimmen.

                        Nur, wenn der User den Parameter ändert (in der URL), habe ich ja erstmal keinen Einfluß drauf.

                        Tja, wenn der Benutzer in der URI herumfuscht und keine Ahnung von URI-Kodierung hat (was man auch nicht erwarten kann), dann ist dein Script gearscht. Du kannst serverseitig höchstens tolerant sein und beide Kodierung annehmen. Mit mb_detect_encoding($string, 'UTF-8, ISO-8859-1') lässt sich z.B. erkennen, ob ein String korrektes UTF-8 ist oder bloß ISO-8859-1. (»k%F6ln« ist inkorrektes UTF-8, also ist es wohl ISO-8859-1.) Je nach Fall kannst du dann rekodieren.

                        Es gibt auch Möglichkeiten, ohne die eher selten installierte mbstring-Extension einen String auf gültiges UTF-8 zu prüfen, das wird im Kommentarbereich von http://de3.php.net/utf8-decode diskutiert. Aber ich glaube, mb_detect_encoding schnitt im Vergleich zu diversen Regulären Ausdrücken am besten ab.

                        Mathias

                        1. Hallo Mathias,

                          Mit mb_detect_encoding($string, 'UTF-8, ISO-8859-1') lässt sich z.B. erkennen, ob ein String korrektes UTF-8 ist oder bloß ISO-8859-1.

                          Aha, Danke für den Hinweis. Funktioniert nun bestens!

                          Mit freundlichem Gruß
                          Micha

      2. Hallo,

        Weil es eben manchmal notwendig ist, strings nach UTF-8 zu kodieren.

        was hat escape() nun mit UTF-8 zu tun? Es wandelt doch nur Steuer- und Sonderzeichen in ihre URL-codierte Form um, also z.B. \r in %0D. Ob der String bzw. das ganze Dokument dabei in UTF-8, ISO-8859-x oder gar Plain ASCII codiert ist, spielt nicht die geringste Rolle.

        So heißen, wenn die Funktion rausfliegt währe JavaScript tatsächlich um eine nützliche Funktion ärmer

        Nö, encodeURI() macht ja genau dasselbe - nur dass hier noch einige Zeichen mehr umcodiert werden, die in URLs auch nichts verloren haben.

        So long,
         Martin

        --
        Heutzutage gilt ein Mann schon dann als Gentleman, wenn er wenigstens die Zigarette aus dem Mund nimmt, bevor er eine Frau küsst.
          (Barbra Streisand, US-Schauspielerin)
        1. Hallo,

          was hat escape() nun mit UTF-8 zu tun? Es wandelt doch nur Steuer- und Sonderzeichen in ihre URL-codierte Form um, also z.B. \r in %0D. Ob der String bzw. das ganze Dokument dabei in UTF-8, ISO-8859-x oder gar Plain ASCII codiert ist, spielt nicht die geringste Rolle.

          Äh... Strings in JavaScript sind erstmal nicht »kodiert«, weil JavaScript Strings nie als Byte-Sequenzen o.ä. sieht, sondern immer nur als Unicode-Zeichen (die intern üblicherweise als UTF-16 gespeichert werden, was einen aber nicht zu interessieren braucht). Bei URL-Kodierung müssen alle Unicode-Zeichen auf US-ASCII abgebildet werden, d.h. escape("ö") ergibt %F6. Dieses 0xF6 ist nichts anderes als die Ein-Byte-Kodierung von ISO-8859-1. In UTF-8 würde dieses Zeichen aber mit zwei Byte kodiert.

          Nö, encodeURI() macht ja genau dasselbe - nur dass hier noch einige Zeichen mehr umcodiert werden, die in URLs auch nichts verloren haben.

          encodeURI nutzt vor allem UTF-8 statt ISO-8859-1.

          Mathias

          1. Hi,

            Äh... Strings in JavaScript sind erstmal nicht »kodiert«, weil JavaScript Strings nie als Byte-Sequenzen o.ä. sieht, sondern immer nur als Unicode-Zeichen

            ... also doch codiert. ;-)
            "Uncodiert" heißt für mich, die reine Bytefolge zu betrachten, ohne sich darum zu kümmern, was sie bedeutet.

            Nö, encodeURI() macht ja genau dasselbe - nur dass hier noch einige Zeichen mehr umcodiert werden, die in URLs auch nichts verloren haben.
            encodeURI nutzt vor allem UTF-8 statt ISO-8859-1.

            Danke, das war mir auch neu.

            Ciao,
             Martin

            --
            Programmierer (m), seltener auch ~in (w):
            Irdische, i.a. humanoide Lebensform, die in einem komplizierten biochemischen Prozess Kaffee, Cola und Pizza in maschinenlesbaren Programmcode umwandelt.
            P~ bilden gelegentlich mit ihresgleichen kleine Gruppen, sogenannte Communities, sind aber ansonsten meist scheue Einzelgänger.
            P~ sind vorwiegend nachtaktiv und ohne technische Hilfsmittel nur eingeschränkt lebensfähig.
  2. if(parent==self) top.location.replace("/?uri="+escape(self.location.href));

    Das ist Blödsinn, href ist bereits kodiert, d.h. du kodierst hier doppelt.

    Das ist eine einfach "Bau dich in ein Frameset ein"-Funktion. Würde an dieser stelle encodeURI eingesetzt würde das doch total falsch.

    genauso wie escape()

    Struppi.