hawkmaster: Cookie UTF-8, Sonderzeichen ??

Hallo zusammen,
ich kann garnicht sagen ob es mehr ein Javascript- oder PHP- Thema ist.
Ich hatte mal vor einiger Zeit ein paar JS Funktionen in meine Web Applikation eingebaut, mit denen ich Cookies schreiben und lesen kann.
Zum trennen von Werte verwende ich unter anderem die zeichen §§§
Und genau dieses macht mir jetzt plötzlich Probleme. Ich weiss nicht genau warum. Vermutlich weil ich meine ganze Applikation auf UTF-8 umgestellt habe?
Ich möchte an eine Stelle die Cookie Werte in einer DB speichern.

  
foreach ($_COOKIE['ServiceID'] as $name => $value) {  
  echo "$name : $value <br />\n";  
  $allproperties = explode("§§§",$value);  
...  
}  

das echo für die Zeichen $$$ ist nun im Browser ���.

4 : Paper Source���4@@@Tray2

Daher funktioniert auch das explode (explode("§§§",$value)) nicht mehr.

  
function setCookies(name) {  
	var ware = new String();  
	var serviceobj = document.forms[0].sel_services.options[document.forms[0].sel_services.selectedIndex];  
	ware += serviceobj.text + "§§§";  
	for(i=0;i<document.forms[0].sel_serviceproperties.length;i++){  
		if (document.forms[0].sel_serviceproperties.options[i].selected == true) {  
			ware += document.forms[0].sel_serviceproperties.options[i].value  + "@@@" + document.forms[0].sel_serviceproperties.options[i].text + "###";  
		}  
	}  
	ware = ware.substring(0, ware.length-3);// '###' am Ende des Strings entfernen  
	alert('Setze Cookie: ' + ware);  
	setzeCookie(name, ware);  
}  
  

Ich weiss nun nicht wo ich ansetzen muss. Ich habe schon die "cookie.js" Datei in UTF8 gespeichert. Dann habe ich versucht $value mit PHP zu decodieren.
$name = utf8_decode($name)

Alles brachte nichts.
Kann mir jemand einen heissen Tipp geben?

vielen Dank und viele Grüße
hawk

  1. Hallo,

    Zum trennen von Werte verwende ich unter anderem die zeichen §§§

    warum ein so "ausgefallenes" Symbol?

    Und genau dieses macht mir jetzt plötzlich Probleme. Ich weiss nicht genau warum. Vermutlich weil ich meine ganze Applikation auf UTF-8 umgestellt habe?

    Gut möglich. Das Symbol "§" hat den Code U+00A7, wird also in UTF-8 durch zwei Bytes dargestellt. Solange du ausschließlich in der Javascript-Welt bleibst, spielt das keine Rolle; Javascript arbeitet intern mit Unicode, unabhängig von der verwendeten Zeichencodierung.

    Wenn aber -so wie es der nachfolgende Codeausschnitt zeigt- PHP ins Spiel kommt, kann's lustig werden, weil PHP nur in ein paar wenigen Funktionen auf die Problematik mit Mehrbyte-Codierungen eingeht.

    foreach ($_COOKIE['ServiceID'] as $name => $value) {

    echo "$name : $value <br />\n";
      $allproperties = explode("§§§",$value);
    ...
    }

      
    
    > das echo für die Zeichen $$$ ist nun im Browser ???.  
      
    Wo kommen jetzt noch die Dollarzeichen her? Und vor allem: Die müssten völlig unproblematisch sein, sie liegen mit Code U+0024 innerhalb des ASCII-Bereichs, der in allen gängigen Codierungen identisch dargestellt wird (UTF-16 nicht, aber das ist auch eher selten).  
      
    Das PHP-Script, das diese "Verarbeitung" und Ausgabe macht, ist vermutlich nicht in UTF-8 codiert. Damit sind die "§§§" als Bytefolge A7,A7,A7 codiert, der Client sendet aber die gleichen Zeichen in UTF-8, das ergibt die Bytefolge C2,A7,C2,A7,C2,A7. Ergo: Keine Übereinstimmung.  
      
    
    > Daher funktioniert auch das explode (explode("§§§",$value)) nicht mehr.  
      
    Eben.  
      
    Eine Darstellung als "???" ist übrigens ein Hilfeschrei des Browsers (oder einer anderen Instanz) beim Interpretieren von fehlerhaften UTF-8-Sequenzen. Das Byte A7 darf in UTF-8 nur als zweites (drittes, ...) Byte einer Mehrbyte-Sequenz auftreten. Einzeln ist es ungültig.  
      
    
    >   if (document.forms[0].sel\_serviceproperties.options[i].selected == true)  
      
    Nur mal so nebenbei: Einen Wert, der schon als Boolean vorliegt, durch einen expliziten Vergleích nochmal in Boolean umzuwandeln, ist unnötig. Ein einfaches  
      
    
    >   if (...options[i].selected)  
      
    genügt und ist leichter zu lesen und zu verstehen.  
      
    
    > Kann mir jemand einen heissen Tipp geben?  
      
     \* Codiere alles in UTF-8, auch die PHP-Scripte  
     \* Vermeide problematische Zeichen in wichtigen Positionen  
      
    So long,  
     Martin  
    
    -- 
    Keine Sorge, wir finden für jede Lösung ein Problem.  
    
    
    1. Hallo Martin,

      warum ein so "ausgefallenes" Symbol?

      Ja, das habe ich ich heute auch schon gefragt :-)
      Nehme ich ein einfacheres (unproblematerisches) dann klappt alles wunderbar.
      Ich wollte dennoch die Ursache wissen.

      das echo für die Zeichen $$$ ist nun im Browser ???.

      Wo kommen jetzt noch die Dollarzeichen her?

      Das war falsch von mir, sorry. Ich meinte natürlich schon die §§§ zeichen werden falsch dargestellt.

      Nur mal so nebenbei: Einen Wert, der schon als Boolean vorliegt, durch einen expliziten Vergleích nochmal in Boolean umzuwandeln, ist unnötig. Ein einfaches

      if (...options[i].selected)

      genügt und ist leichter zu lesen und zu verstehen.

      Danke für den Hinweis:

      * Codiere alles in UTF-8, auch die PHP-Scripte

      Also eigentlich ist alles in UTF-8 kodiert. Das "cookie.js" Script hatte ich zuerst vergessen, aber das ist nun auch in UTF-8.
      Auch meine ganzen PHP Seiten laufen in UTF-8.

      Was ich allerdings nicht weiss ist wie man das Cookie selbst in UTF-8 kodiert?

      vielen Dank und viele Grüße
      hawk

  2. Hi!

    das echo für die Zeichen $$$ ist nun im Browser ���.

    Diese Zeichen bekommst du, wenn keine gültige UTF-8-Sequenz vorliegt. Das wäre der Fall, wenn die §§§ zum Beispiel ISO-8859-1-kodiert vorliegen. Lass dir die Hex-Werte anzeigen, dann siehst du vermutlich A7 statt C2 A7. url_encode() lässt sich gut zur Hex-Anzeige missbrauchen, ansonsten auch bin2hex().

    Vermutlich weil ich meine ganze Applikation auf UTF-8 umgestellt habe? [...] Dann habe ich versucht $value mit PHP zu decodieren. $name = utf8_decode($name)

    Dann musst du deine Kekse erst einmal nach UTF-8 umkodieren und nicht nach ISO-8859-1.

    Lo!

    1. Hallo dedlfix,

      auch dir vielen Dank für deine Hilfe.

      Dann musst du deine Kekse erst einmal nach UTF-8 umkodieren und nicht nach ISO-8859-1.

      Tja, ich habe schon deswegen gegoogelt. Aber wie kann man das machen?

      vielen Dank und viele Grüße
      hawk

      1. Hi!

        Dann musst du deine Kekse erst einmal nach UTF-8 umkodieren und nicht nach ISO-8859-1.
        Tja, ich habe schon deswegen gegoogelt. Aber wie kann man das machen?

        Na, utf8_encode(). Wie der Browser (FF) dazu kommt, ISO-8859-1 zu verwenden hab ich nicht herausgefunden.

        Lo!

        1. Hallo dedlfix,

          Na, utf8_encode(). Wie der Browser (FF) dazu kommt, ISO-8859-1 zu verwenden hab ich nicht herausgefunden.

          Hmm, jetzt nur nochmals zum Verständnis.
          Alle meine PHP Seiten laufen in UTF-8. Die Javascript Datei (cokkies.js) ist nun auch in UTF-8 gespeichert.
          Das setzen des Cookie passiert ja auch in dieser Datei.
          function setzeCookie(name, wert) {
          ..
          }

          Wo soll ich nun noch das "utf8_encode()" unterbringen?

          vielen Dank und viele Grüße
          hawk

          1. Hi!

            Wo soll ich nun noch das "utf8_encode()" unterbringen?

            Du sollst die genannten oder andere Werkzeuge zur Hexadezimaldarstellung verwenden und schauen, welche Kodierung zu welchem Zeitpunkt vorliegt, um sie dann in eine passendere umzukodieren.

            Kannst du beim Javascript-Cookie-Speichern eine Kodierung angeben? Nein, macht der Browser anscheinend[*] wie er denkt. Lediglich mit encodeURIComponent kann man da was hinbiegen, obwohl es nicht dafür gedacht ist.

            Kannst du beim Lesen von $_COOKIE[] eine Umkodierung vornehmen?
            ( ) Ja
            ( ) Nein

            [*] Selbst ein 德国, das mit alert() ordentlich ausgegeben wird, landet in document.cookie nur in undefinierter Form (B7FD).

            Lo!

            1. Hallo

              Kannst du beim Lesen von $_COOKIE[] eine Umkodierung vornehmen?
              ( ) Ja
              ( ) Nein

              nun, das habe ich ja schon geschrieben das ich es beim Lesen versucht hatte:
              foreach ($_COOKIE['ServiceID'] as $name => $value) {
                $name = utf8_encode($name);
              ...
              }

              auch das brachte nichts.

              vielen Dank und viele Grüße
              hawk

              1. Hi!

                Kannst du beim Lesen von $_COOKIE[] eine Umkodierung vornehmen?
                ( ) Ja
                ( ) Nein

                nun, das habe ich ja schon geschrieben das ich es beim Lesen versucht hatte:
                foreach ($_COOKIE['ServiceID'] as $name => $value) {
                  $name = utf8_encode($name);
                ...
                }

                Du schreibst im OP von utf8_decode(), was aber das falsche ist. Jetzt schreibst du utf8_encode(), was erst einmal Abhilfe bringen müsste. Meinst du das jetzt wirklich so oder ist das ein Vertipper?

                auch das brachte nichts.

                "Nichts" gibt es beim Programmieren nicht. Welches Ergebnis konkret bekommst du? Am besten auch in Hex-Ansicht darstellen.

                Lo!

              2. Hi,

                nun, das habe ich ja schon geschrieben das ich es beim Lesen versucht hatte:
                foreach ($_COOKIE['ServiceID'] as $name => $value) {
                  $name = utf8_encode($name);
                ...
                }

                auch das brachte nichts.

                du willst doch vermutlich auch nicht den *Namen*, sondern den Cookie-*Wert* umcodieren - oder nicht?

                Davon abgesehen finde ich etliche Stellen im Internet, die behaupten, dass in Cookies die gleichen Beschränkungen hinsichtlich erlaubter Zeichen gelten wie in URLs, und dass nicht erlaubte Zeichen (non-ASCII, Space, etc.) URL-encoded sein sollten. Das würde dein Problem mit dem § im Cookie zumindest teilweise erklären.

                Ciao,
                 Martin

                --
                Nicht jeder, der aus dem Rahmen fällt, war vorher im Bilde.
                1. Hi!

                  Davon abgesehen finde ich etliche Stellen im Internet, die behaupten, dass in Cookies die gleichen Beschränkungen hinsichtlich erlaubter Zeichen gelten wie in URLs, und dass nicht erlaubte Zeichen (non-ASCII, Space, etc.) URL-encoded sein sollten.

                  Ah, gut, dann also doch http://de.selfhtml.org/javascript/objekte/unabhaengig.htm#encode_uri_component@title=encodeURIComponent().

                  Lo!

  3. hi,

    Ich möchte an eine Stelle die Cookie Werte in einer DB speichern.

    Welche Werte kann denn Dein Cookie annehmen, bzw. hast Du sichergestellt, dass da nur ASCII-Zeichen sind?

    Btw., Dein Trennzeichen § ist nicht in der ascii-Tabelle, denn die geht nur bis 127 (7bit).

    Stelle sicher, dass da nur 7bit codierte Zeichen sind und alles wird gut. RFC 2616

    Hotti

    HTTP per IO-Socket

  4. Hallo

    Ich weiss nun nicht wo ich ansetzen muss. Ich habe schon die "cookie.js" Datei in UTF8 gespeichert. Dann habe ich versucht $value mit PHP zu decodieren.

    Du musst nur zwei Dinge beachten.

    a) Das alte Cookie ist ein ISO-8859-15-Zeichen, also beim Lesen musst du prüfen, ob es ein ISO-8859-15-er "&&&" oder ein utf-8-er "&&&". Das sind zwei Stringvergleiche.
    b) beim Schreiben setzt du nur das utf-8-er "&&&".

    Herzliche Grüße
    Wolfgang

    1. Hi!

      a) Das alte Cookie ist ein ISO-8859-15-Zeichen, also beim Lesen musst du prüfen, ob es ein ISO-8859-15-er "&&&" oder ein utf-8-er "&&&". Das sind zwei Stringvergleiche.

      Es ist kein UTF-8-kodiertes Cookie. Jedenfalls schrieb er nicht, dass er das betroffene Cookie auch mit PHP setzt und weder FF noch IE nehmen UTF-8 zum Schreiben von Cookie-Daten.

      b) beim Schreiben setzt du nur das utf-8-er "&&&".

      Das Schreiben soll mit Javascript erfolgen. Javascript bietet keine Möglichkeit, eine Zeichenkodierung anzugeben, die genommen werden soll. Wie ich herausfand, gehen Zeichen mit Unicode-Codepoints oberhalb 255 kaputt und wie Martin herausfand, ist die Lösung, eine URL-kodierung zu verwenden. Wenn man dazu encodeURIComponent() nimmt, sind alle Unicode-Zeichen verwendbar, weil diese durch encodeURIComponent() zuerst UTF-8- und anschließend URL-kodiert werden. PHP entfernt eine URL-Kodierung selbst, so dass in $_COOKIE schönes UTF-8 enthalten ist.

      Lo!