yens: Javascript-Array übermitteln

Hi,

ich muss ein Javascript-Array, das den Status aller auf der Website enthaltenen Bilder angibt (angewählt/abgewählt), an den Server übermitteln, damit er diese als zip-Datei zum Download bereitstellt.

Ich hatte bis jetzt nur die Möglichkeit gefunden, für jedes Bild eine Checkbox einzurichten, dadurch entstand aber ein sehr unschöner Effekt, der mir das Layout zersprengte. Dann habe ich die etwa 200 Checkbox an das untere Ende der Website gelegt, was natürlich auch nicht das Gelbe vom Ei ist.

Gibt es eine bessere Möglichkeit, das Array zu übermitteln?

Grüsse
Jens

  1. Moin Moin!

    Gibt es eine bessere Möglichkeit, das Array zu übermitteln?

    Vielleicht nicht besser, aber anders. Klarer Nachteil der Methode: Ohne Javascript funktioniert gar nichts, im Gegensatz zu Checkbuttons.

    Ich gehe erstmal davon aus, dass jedes Bild eine numerische ID hat. Dann kannst Du mittels Array.join() (http://de.selfhtml.org/javascript/objekte/array.htm#join) die IDs der ausgewählten Bilder bei jeder Auswahländerung in ein Hidden-Feld schreiben, getrennt mit einem Zeichen Deiner Wahl, z.B. einem Komma. Auf dem Server zerlegst Du das Feld an Kommata und hast wieder ein Array, aus dem Du dann die gültigen IDs gerausfischst. (In Perl: my @a=grep { /^\d+$/ && isValidId($_) } split ',',param("arrayname");)

    Solltest Du die Bilder per Namen ansprechen, geht das prinzipiell genauso. Du benötigst dann allerdings ein Trennzeichen, das garantiert nicht in den Namen vorkommt. ASCII NUL (0x00) wäre ein Kandidat für so ein Zeichen. Die Schwierigkeit hier ist die serverseitige Überprüfung der Bildnamen, um nicht versehentlich Dateien zu liefern, die man besser nicht ausgeliefert hätte. Man stelle sich ein Bild namens "../../../../etc/passwd" oder "../all-my-secret-passwords.php" vor.

    Aber ich gehe mal fröhlich davon aus, dass Du dieses Problem entweder schon gelöst hast oder es Dir völlig egal ist. Falls nicht, ein kleiner Tipp: Stelle auf IDs um oder beschränke die für Namen erlaubten Zeichen (white list). Typisch für eine Whitelist-Prüfung wäre z.B. $filename=~/[1]+.(jpg|jpeg|gif|png)$/ or die "Don't try to hack my script";.

    Warum keine Blacklist verbotener Zeichen? "Nenne alle problematischen Zeichen!" -- "Slash und Backslash" -- "Was ist mit dem Punkt?" -- "Harmlos" -- "Auch alleine oder zu zweit?" -- "OK, Slash, Backslash, Punkt." -- "Was ist mit dem Stern?" -- "Ooops, glob() übersehen. Stern ist auch nicht gut. Und Fragezeichen wohl auch nicht." Und so weiter. Es gibt noch wesentlich mehr problematische Zeichen. Und sie alle abzudecken ist schwieriger, als eine sehr strikte Liste erlaubter, nachweislich harmloser Zeichen zusammenzusammeln. Ein fehlendes Zeichen in der Blacklist und schon ist alles verloren. Ein fehlendes Zeichen in der Whitelist und der User nörgelt.

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so".

    1. a-z0-9._- ↩︎

    1. Hi,

      danke erstmal für deine Antwort! Ich habe die Bilder natürlich numeriert!
      Das große Problem, was ich nun habe, ist aber gar nicht, ob Array oder Variable, sondern wie bekomme ich eine JS-Variable auf den Server?

      Ich hab schon versuch das Value-Attribut eines Hidden-Inputs umzuschreiben, leider erfolglos. Code:

      function add2sel(id,name)
      {
       if(document.getElementById(id).value) {
        document.getElementById(id).value=false;
       } else {
        document.getElementById(id).value=name;
       }
      }

      Der Value wird einfach nicht umgeschrieben, obwohl der Else-Zweig theoretisch greift, hab ich schon mit einem alert getestet.

      MFG
      Jens

      1. Falls jemanden das ganze verwirrt, ich hab hier noch mit einem hidden input pro Bild gearbeitet, d.h. "getElementById(id)" steht für den input und die Variable "name" enthält die Datenbank-Id des zugehörigen Bildes...

        1. Moin Moin!

          Du solltest nicht über getElementByID() arbeiten, damit schließt Du unnötig ältere Browser aus. document.forms["Formularname"].elements["Elementname"] ist der kompatiblere Weg.

          Das value-Attribut der Elemente ist immer ein String, etwas anderes zuzuweisen wird zu unerwünschten Ergebnissen führen.

          Wenn Du den Javascript-Firlefanz weitgehend sein läßt und stattdessen Dein Design überarbeitest, brauchst Du dich darum gar nicht zu künnern. Du definierst pro Bild eine Checkbox, deren Value jeweils die Bild-ID ist. Beim Absenden des Formulars wird jede angekreuzte Checkbox separat mit ihrem Namen und Value übertragen:

          <form action="zipit.cgi" method="get" name="auswahl">
            <input type="checkbox" name="images" value="14" checked><img src="14.jpg" alt=""><br>
            <input type="checkbox" name="images" value="15"><img src="15.jpg" alt=""><br>
            <input type="checkbox" name="images" value="16" checked><img src="16.jpg" alt=""><br>
            <input type="submit" value="Zippen">
            </form>

          Wenn Du dieses Formular ohne Änderungen abschickst, wird auf dem Server die URL zipit.cgi?images=14&images=16 aufgerufen. Du bekommst den images-Parameter also mehrfach, mit Werten für alle angekreuzten Checkboxen. PHP kann damit meines Wissens nur dann umgehen, wenn der Name auf "[]" endet. Andere Systeme haben dieses Problem nicht.

          Das ganze "hübsch" zu machen ist die Aufgabe von CSS, nicht Javascript. Du kannst natürlich, sofern Javascript aktiviert ist, die Checkboxen per display:none verschwinden lassen, onclick-Events auf die Bilder an die Checkboxen weiterleiten, und abhängig vom Status der jeweiligen Checkbox das Bild umstylen (z.B. border-color:red vs. border-color:green). Die Grundfunktion bleibt so auch ohne Javascript erhalten.

          Wenn Du unbedingt auf einer Javascript-Lösung bestehst, wirst Du ein Array benötigen, in dem Du entweder den "Ausgewählt"-Status jedes einzelnen Bildes (anhand seiner ID) selbst pflegst oder nur ausgewählte Bilder-IDs speicherst und bei jeder Änderung den Wert eines Hidden-Feldes nachziehst. Du brauchst also mindestens einen recht aufwendigen onclick-Handler, der das Array umgräbt. Eine von vielen Code-Zeilen in dem onclick-Handler wird sinngemäß so aussehen, wenn das Array nur IDs ausgewählter Bilder enthält:

          document.forms["formularName"].elements["hiddenFieldName"].value=selectedImagesArray.join(",");

          Davor muß das Array auf den neuesten Stand gebracht werden.

          Die Lösung mit Checkboxen und CSS ist definitiv einfacher.

          Alexander

          --
          Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so".
  2. Hi Jens,

    Ich hatte bis jetzt nur die Möglichkeit gefunden, für jedes Bild eine Checkbox einzurichten, dadurch entstand aber ein sehr unschöner Effekt, der mir das Layout zersprengte. Dann habe ich die etwa 200 Checkbox an das untere Ende der Website gelegt, was natürlich auch nicht das Gelbe vom Ei ist.

    1. Das hört sich doch nach'nem (X)HTML Problem an, das lösbar sein sollte. Deine jetzige Lösung (erst 200 Bilder, dann 200 checkboxen darunter): wie soll der User da noch "seine" Bilder ausfindig machen?

    2. Für eine Lösung bzgl. der Übermittlung der Werte wäre es ganz hilfreich zu wissen, was auf deinem Server läuft. Mit PHP etwa könntest du doch relativ einfach über $_POST auf die Werte zugreifen? Sag doch mal...

    Gruß
    Antipitch

  3. Gibt es eine bessere Möglichkeit, das Array zu übermitteln?

    Besser als ein Formular? Nein, denn alles andere hängt von Javascript ab. Für die Übermittlung von komplexen Datenstrukturen gibt es übrigens JSON, m.W. unterstützt PHP dieses "Austauschformat" ab Version 5.2 nativ.

    Siechfred

    --
    Wir vom Moderatorenteam haben keinerlei Humor, von dem wir wüssten.