Ergebnis 1 bis 6 von 6

Thema: Java Skript - Cookie wird nicht neu gesetzt

  1. #1

    Java Skript - Cookie wird nicht neu gesetzt

    Aloha Programmierforum,

    ich komme momentan mit einem Problem absolut nicht weiter. Ich arbeite momentan mit Cookies. Ich lasse Werte in ein Cookie schreiben und will diese sowohl verändern als auch auslesen lassen.
    Die Cookie sind dabei wie folgt aufgebaut:

    Code:
     attribut=wert1°wert2°expires=date; attribut2=wert1°wert2°expires=date
    Heisst also das Semikolon ist der Delimiter für die Attribute und das ° wiederum für die einzelnen Werte des Attributs.
    Klingt soweit nicht weiter wild. Dachte ich auch. Bis folgendes passierte:

    In der folgenden HTML Datei setze ich 2 Attribute mit jewals 2 Werten.
    Das lasse ich mir in einem Popup ausgeben.
    Danach versuche ich in beiden Cookies jewals einen Wert zu ersetzen. Danach gebe ich den Inhalt des Cookies wieder aus.

    HTML-Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>Cookie Test</title>
    <script type="text/javascript" src="CookieUtil.js"></script>
    </head>
    <body>
    
    <script type="text/javascript">
    // Cookiedaten schreiben
    var date = new Date();
    date.setTime(date.getTime() + 60000);
    addCookieAttr("test","1°String1°", date);
    addCookieAttr("test2","2°String2°", date);
    
    // Cookiedaten zeigen vor Manipulation
    alert("Cookieinhalt: "+document.cookie);
    
    // Cookiedaten veraendern
    replaceCookieAttrValue("test","String1","String_1");
    replaceCookieAttrValue("test2","String2","String_666");
    
    //Cookiedaten zeigen
    document.write(document.cookie);
    </script>
    
    
    </body>
    </html>
    Das interessante ist nun, es lassen sich immer nur Werte des ersten Attributs ändern. Nie einer danach. Also fing ich an zu testen und habe das ganze bis zu einem Punkt aufgeschlüsselt an dem ich nicht mehr weiter weiss. Das ist die Funktion die die Ersetzungen durchführen soll:

    Code (javascript):
     
    /**
     * Ersetzt den Wert eines Attributes durch einen uebergebenen Wert.
     * @param name Der Name des Attributes
     * @param searchedAttr Der Wert im Attribut der ersetzt werden soll
     * @param replaceAttr Der Wert der den alten ersetzen soll
     * @return Gibt 1 zurueck falls die Ersetzung erfolgreich war, ansonsten -1
     */
    function replaceCookieAttrValue(name,searchedAttr,replaceAttr){
    	var retVal = -1;
     
    	if(name){	
    		var cookieContent = getCookieAttrValue(name); // Sich das Attribut holen, in dem ein Wert ersetzt werden soll
    		var replaceString = cookieContent.replace(searchedAttr,replaceAttr); // Den Wert ersetzen
     
    		if(cookieContent.search(replaceString) == -1){ // Ueberpruefen ob die Ersetzung erfolgreich war
    			retVal = 1;
    			alert("Replacestring: "+replaceString); // Debug wie der String zum ersetzen aussieht
    			alert("Replace: "+document.cookie.replace(cookieContent , replaceString)); // Was gibt die Funktion zurueck die ersetzen soll?
    			document.cookie =  document.cookie.replace(cookieContent , replaceString); // Hier soll die Ersetzung auf das Cookie angewand werden
    		}		
    	}
     
    	return retVal;	
    }
     


    Dieser Code funktioniert wie gesagt wunderbar solange man es auf Werte des ersten Attributs anwendet. Bei jedem darauffolgenden geht es simpel nicht.
    Das interessante hierbei ist wirklich das man in der Debugausgabe sieht das der replaceString aufs haar genau den richtigen String enthält. Bei der Zeile an der dem Cookie jedoch der neue Wert zugewiesen werden soll happert es. Wie kann das jedoch bei einer Zuweisung der Fall sein? Beachte ich da irgendeine Eigenart von JS nicht? Das Problem taucht übrigens im IE6 ( dem Browser in dem es funktionieren soll ) als auch im aktuellsten Firefox auf.
    Vorallem aber, warum funktioniert es beim ersten Attribut so problemlos?


    Die anderen zwei Funktionen die hier für eine Rolle spielen.
    Diese zwei tun allerdings soweit das was sie tun sollen. Sind also eher der Verständnis halber mit dabei.

    Code (javascript):
    var valueDelimiter = '°', attributDelimiter = ';';


    Code (javascript):
     
    /**
     * Setzt ein neues Attribut mit einem Wert in dem Seitencookie.
     * @param name Der Name des Attributes
     * @param value Der Wert des Attributes, mehrere Werte sind moeglich muessen aber durch den 
     * Delimiter '°' getrennt werden. z.B.: "wert1°wert2°"
     * @param expires(optional) Ein UTC-Date als String, beschreibt die Lebensdauer des Cookies
     */
    function addCookieAttr(name,value,expires){
    	var cook = name + '=' + value;
    	cook += (expires) ? "expires=" + expires + attributDelimiter : "";
     	document.cookie = cook;
    }
     


    Code (javascript):
     
    /**
     * Liefert den Wert eines Attributes.
     * @param name Der Name des Attributes
     * @return Den Wert des Attributes, der Inhalt kann Einzelwerte besitzen die durch den Delimiter '°' 
     * getrennt sind. z.B.: "wert1°wert2°" Liefert null zurueck wenn kein Wert gefunden wurde.
     */
    function getCookieAttrValue(name){
    	var retVal = "", searchString = name + '=', startIndex = document.cookie.search(searchString);
     
    	if(startIndex != -1){		
    		startIndex += searchString.length;
     
    		// Attribut ausschneiden lassen
    		var endIndex = document.cookie.indexOf(attributDelimiter,startIndex);
    		if(endIndex == -1) endIndex = document.cookie.length;
    		var content = document.cookie.substring(startIndex,endIndex);
     
    		// Wert im Attribut ausschneiden
    		endIndex = content.lastIndexOf(valueDelimiter);
    		retVal = content.substring(0 , endIndex + 1);
     
    	}else{
    		retVal = null;
    	}
    	return retVal;
    }  
     


    Wer mir helfen möchte, wird sicherlich selbst probieren wollen.
    Aus dem Grund hier die zwei Dateien die ich hier benutze.
    [Klick mich]

    Hoffe jemand weiß da Rat.

    Geändert von makenshi (29.11.2009 um 04:08 Uhr)

  2. #2
    Code (JavaScript):
     
    function addCookieAttr(name,value,expires){
    	var cook = name + '=' + value;
    	cook += (expires) ? "expires=" + expires + attributDelimiter : "";
     	document.cookie = cook;
    }
     


    (expires) ? "expires=" + expires + attributDelimiter : "";

    sollte

    (expires) ? "expires=" + expires + attributDelimiter : attributDelimiter;

    heißen, denn ansonsten kann es zu fehlenden Semikola und damit Parsing-Problemen führen.

    Außerdem überschreibt document.cookie = cook; jedes mal den Cookie und fügt nicht neue Attribute hinzu. Damit enthält der Cookie immer nur das letzte Attribut, das du "hinzugefügt" hast.

    Code (JavaScript):
     
    function replaceCookieAttrValue(name,searchedAttr,replaceAttr){
    	var retVal = -1;
     
    	if(name){	
    		var cookieContent = getCookieAttrValue(name);
     
    		if(cookieContent != null){
    			var replaceString = cookieContent.replace(searchedAttr,replaceAttr);
     
    			if(cookieContent.search(replaceString) == -1){
    				retVal = 1;
    				alert("Replacestring: "+replaceString);
    				alert("Replace: "+document.cookie.replace(cookieContent , replaceString));
    				document.cookie =  document.cookie.replace(cookieContent , replaceString);
    			}		
    		}
    	}
     
    	return retVal;	
    }
     


    if(cookieContent.search(replaceString) == -1){

    macht keinen Sinn.

    cookieContent.search(replaceString)

    sollte

    replaceString.search(replaceAttr)

    heißen, denn replace() verändert nicht den String, auf dem es angewendet wird, sondern gibt einen neuen String zurück, der aus dem alten inklusive den Veränderungen (falls etwas verändert wurde) besteht. Weiter gibt search() nur in dem Fall -1 zurück, wenn die Suche nicht erfolgreich war, du musst also nicht auf Gleichheit, sondern auf Ungleichheit prüfen. Damit sollte die Zeile, soweit ich das sehe

    if(replaceString.search(replaceAttr) != -1){

    heißen.


    Edit: Mit JSON könntest du dir übrigens das Leben auch einfacher machen.

    Geändert von Kyuu (29.11.2009 um 17:58 Uhr)

  3. #3
    Zitat Zitat von Kyuu Beitrag anzeigen
    Code (JavaScript):
     
    function addCookieAttr(name,value,expires){
    	var cook = name + '=' + value;
    	cook += (expires) ? "expires=" + expires + attributDelimiter : "";
     	document.cookie = cook;
    }
     


    (expires) ? "expires=" + expires + attributDelimiter : "";

    sollte

    (expires) ? "expires=" + expires + attributDelimiter : attributDelimiter;

    heißen, denn ansonsten kann es zu fehlenden Semikola und damit Parsing-Problemen führen.
    Anscheinend ist leider beides falsch. Das Expire Attribut scheint gar nicht im eigentlich Wert vorkommen zu dürfen. Ich werd es von daher mal hinten drancaten.

    Zitat Zitat von Kyuu Beitrag anzeigen
    Außerdem überschreibt document.cookie = cook; jedes mal den Cookie und fügt nicht neue Attribute hinzu. Damit enthält der Cookie immer nur das letzte Attribut, das du "hinzugefügt" hast.
    Nein. Ein Cookie verhält sich nicht wie ein normaler String. Es ist ja wie gesagt auch die Sache das das bis dahin wunderbar funktioniert. Es werden mit der Methode genau auf dem Wege zwei Cookies erstellen. Ja, zwei verschiedene. Wie gewollt also eigentlich. Soweit ich mir das vorhin angelesen habe, scheint man bei einem Cookie eher Zugriff auf die Paare von Werten. Auch wenn man es , zumindestens theoretisch, als String behandeln kann.

    Zitat Zitat
    if(cookieContent.search(replaceString) == -1){

    macht keinen Sinn.

    cookieContent.search(replaceString)

    sollte

    replaceString.search(replaceAttr)

    heißen, denn replace() verändert nicht den String, auf dem es angewendet wird, sondern gibt einen neuen String zurück, der aus dem alten inklusive den Veränderungen (falls etwas verändert wurde) besteht. Weiter gibt search() nur in dem Fall -1 zurück, wenn die Suche nicht erfolgreich war, du musst also nicht auf Gleichheit, sondern auf Ungleichheit prüfen. Damit sollte die Zeile, soweit ich das sehe

    if(replaceString.search(replaceAttr) != -1){

    heißen.
    Doch, das hat schon so seinen Sinn.
    Im replaceString befindet sich der neu zu setzende String. Heisst also die Abfrage soll abfragen ob die zwei Strings eben nicht dem anderen gleichen. Wenn nämlich der Original Inhalt in cookieContent dem Inhalt von replaceString gleicht, dann wurde in replaceString keine Ersetzung vorgenommen. Ist quasi als Sicherheitsabfrage gedacht.

    Das replace() nur einen String zurückliefert und nicht automatisch etwas verändert ist mir bekannt. Anders benutze ich es ja im Code auch nirgendwo.


    Zitat Zitat
    Edit: Mit JSON könntest du dir übrigens das Leben auch einfacher machen.
    Dankeschön, sieht nützlich aus. Ist aber wahrscheinlich nichts was ich im aktuellen Projekt einbinden darf. Die Aufgabenstellung ist reiner eigener Code. Keine fremden Biblotheken oder ähnliches.


    Also alles in allem scheint das Problem daran zu liegen das ich auf die Wertepaare falsch zugreife. So wie es aussieht kann ich den Cookie nicht als normalen String sehen. http://www.quirksmode.org/js/cookies.html <-- Zumindestens hier nach.

    Danke trotzdem für deine Hilfe Kyuu. ^^

  4. #4
    Zitat Zitat von makenshi Beitrag anzeigen
    Nein. Ein Cookie verhält sich nicht wie ein normaler String. Es ist ja wie gesagt auch die Sache das das bis dahin wunderbar funktioniert. Es werden mit der Methode genau auf dem Wege zwei Cookies erstellen. Ja, zwei verschiedene. Wie gewollt also eigentlich. Soweit ich mir das vorhin angelesen habe, scheint man bei einem Cookie eher Zugriff auf die Paare von Werten. Auch wenn man es , zumindestens theoretisch, als String behandeln kann.
    Ok, da zeigt sich, dass ich kein Webentwickler bin. Aber dennoch möchte ich kommentieren, dass ich dieses kontraintuitive Verhalten äußerst dämlich finde. Wenn ich a gleich b setze, erwarte ich, dass a im Nachhinein auch gleich b ist. Wer auch immer dafür verantwortlich ist, sollte sich in Grund und Boden schämen.

    Zitat Zitat von makenshi Beitrag anzeigen
    Doch, das hat schon so seinen Sinn.
    Im replaceString befindet sich der neu zu setzende String. Heisst also die Abfrage soll abfragen ob die zwei Strings eben nicht dem anderen gleichen. Wenn nämlich der Original Inhalt in cookieContent dem Inhalt von replaceString gleicht, dann wurde in replaceString keine Ersetzung vorgenommen. Ist quasi als Sicherheitsabfrage gedacht.
    Da wären wir wieder bei kontraintuitivem Verhalten. ;) Dass du da das Pferd von hinten aufzäumst, fällt beim ersten Blick nicht auf. Was man da erwartet, ist, dass replaceString auf ein Vorkommen von replaceAttr überprüft wird (in welchem Fall eben eine Ersetzung stattfand). Wenn du wirklich die beiden Strings auf Un- bzw. Gleichheit überprüfen willst, wieso nicht einfach != bzw. == benutzen?

    Zitat Zitat von makenshi Beitrag anzeigen
    Also alles in allem scheint das Problem daran zu liegen das ich auf die Wertepaare falsch zugreife. So wie es aussieht kann ich den Cookie nicht als normalen String sehen. http://www.quirksmode.org/js/cookies.html <-- Zumindestens hier nach.
    Alles was du nach dieser Seite beachten musst, ist wie Cookies gesetzt werden, also zum Beispiel, dass zur gleichen Zeit nur ein Wert gesetzt werden kann und ein bestimmtes Format eingehalten werden muss. document.cookie gibt ja immer noch einen vollwertigen String zurück, der aber natürlich etwas anders aufgebaut ist, als du gedacht hast.

    Geändert von Kyuu (29.11.2009 um 21:25 Uhr)

  5. #5
    Zitat Zitat von Kyuu Beitrag anzeigen
    Ok, da zeigt sich, dass ich kein Webentwickler bin. Aber dennoch möchte ich kommentieren, dass ich dieses kontraintuitive Verhalten äußerst dämlich finde. Wenn ich a gleich b setze, erwarte ich, dass a im Nachhinein auch gleich b ist. Wer auch immer dafür verantwortlich ist, sollte sich in Grund und Boden schämen.
    Kein Ding, ich bin davon genau so vom Blitz getroffen worden. Anscheinend werden da auf irgendeine kranke Art und Weise setter aufgerufen die die entsprechenden Attribute dann setzen. Sowas kann ich auch absolut nicht nachvollziehen.


    Zitat Zitat
    Da wären wir wieder bei kontraintuitivem Verhalten. Dass du da das Pferd von hinten aufzäumst, fällt beim ersten Blick nicht auf. Was man da erwartet, ist, dass replaceString auf ein Vorkommen von replaceAttr überprüft wird (in welchem Fall eben eine Ersetzung stattfand). Wenn du wirklich die beiden Strings auf Un- bzw. Gleichheit überprüfen willst, wieso nicht einfach != bzw. == benutzen?
    Wo du natürlich Recht hast. x)
    Das ist glaube ich an sich meine stellenweise verdrehte Logik.
    Besser wäre es aber definitiv den veränderten String auf ein Vorkommen von replaceAttr zu überprüfen. Werd ich denk ich morgen auch mal umändern.

    Zitat Zitat
    Alles was du nach dieser Seite beachten musst, ist wie Cookies gesetzt werden, also zum Beispiel, dass zur gleichen Zeit nur ein Wert gesetzt werden kann und ein bestimmtes Format eingehalten werden muss. document.cookie gibt ja immer noch einen vollwertigen String zurück, der aber natürlich etwas anders aufgebaut ist, als du gedacht hast.
    Naja, an sich dürfte es dem Cookie hoffentlich egal sein wie ich den Wert zusammenbaue. Solange ich keine Delimiter benutze die der Cookie benutzt. Hoffe ich. Ich werd auf jeden Fall morgen schauen das ich den Cookie anständig generiert bekomme. Mithilfe der Informationen von der Seite dürfte das aber einfach werden.

    Vielleicht bemerke ich bei der Gelegenheit dann auch wodran die vorherige Methode scheiterte. Ich schätz aber simpel am bereits vorliegenden Aufbau der Cookies.

    Geändert von makenshi (29.11.2009 um 23:59 Uhr)

  6. #6
    Zitat Zitat von makenshi Beitrag anzeigen
    Naja, an sich dürfte es dem Cookie hoffentlich egal sein wie ich den Wert zusammenbaue. Solange ich keine Delimiter benutze die der Cookie benutzt. Hoffe ich.
    Klar. Ich meinte eher sowas wie document.cookie = "attr1=val1; attr2=val2; ...". ;)

    Falls du noch nicht herausgefunden hast, woran das Ersetzen scheiterte:

    Das Problem ist die Zeile

    document.cookie = document.cookie.replace(cookieContent , replaceString);

    document.cookie liefert einen String der Form

    "attr1=val1; attr2=val2; attr3=val3;"

    Nun ersetzt du zum Beispiel val2 durch val222 und erhältst den String

    "attr1=val1; attr2=val222; attr3=val3;"

    den du mit

    document.cookie = "attr1=val1; attr2=val222; attr3=val3;"

    versuchst zu speichern. Das Problem ist nun (wie aus der von dir gelinkten Seite hervorgeht), dass der interne Cookie-Setter nur Strings der Form "name=value; expiry=... ; path=..." akzeptiert, das heißt, es gehen alle Name-Value-Paare nach dem ersten Name-Value-Paar verloren und damit kann auch immer nur das erste Name-Value-Paar verändert werden. Die Lösung ist denkbar einfach: extrahiere das gewünschte Name-Value-Paar aus dem String, der vom Cookie-Getter zurückgegeben wird und arbeite damit weiter.

    Geändert von Kyuu (30.11.2009 um 15:27 Uhr)

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •