Mehrere Bilder an Server senden

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Mehrere Bilder an Server senden

    Hallo zusammen,

    ich möchte mehrere Bilder auf meinen Server hochladen.
    Der Code unten Funktioniert bereits sehr gut für einzelne Bilder.
    Was muss ich an dem Code verändern um mit dem selben Request ein zweites Bild zu senden?
    Und wie muss ich das dann in meinem PHP Script behandeln?

    Client Code:

    Brainfuck-Quellcode

    1. UIImage *yourImage= [UIImage imageNamed:@"image.jpg"];
    2. NSData *imageData = UIImageJPEGRepresentation(yourImage, 0.5);
    3. NSString *urlString = @"http://jonasester.de/Scout/Upload.php";
    4. NSMutableURLRequest *request = [[NSMutableURLRequest alloc]init];
    5. [request setURL:[NSURL URLWithString:urlString]];
    6. [request setHTTPMethod:@"POST"];
    7. NSString *boundary = @"---------------------------14737809831466499882746641449";
    8. NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
    9. [request addValue:contentType forHTTPHeaderField:@"Content-Type"];
    10. NSMutableData *body = [NSMutableData data];
    11. [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    12. [body appendData:[@"Content-Disposition: form-data; name=\"userfile\"; filename=\"myImage.jpg\"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    13. [body appendData:[@"Content-Type: application/octet-stream\r\n\r\n"dataUsingEncoding:NSUTF8StringEncoding]];
    14. [body appendData:[NSData dataWithData:imageData]];
    15. [body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    16. [request setHTTPBody:body];
    17. [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
    Alles anzeigen


    PHP

    PHP-Quellcode

    1. <?php
    2. $fileName = $_FILES['userfile']['name'];
    3. $path = "Bilder/" . $fileName;
    4. move_uploaded_file($_FILES['userfile']['tmp_name'], $path);
    5. ?>

  • Anscheinend sendest Du die Daten als Formulardaten (MIME-Multipart). Da kannst Du mehrere Blöcke mit Daten reinhängen, so wie das die Zeilen 14 bis 18 machen. Allerdings steckt auch hier immer der Teufel im Detail. Hier findest Du eine kompaktere Beschreibung über den Aufbau der Nachricht inklusive einer Klasse, die Dir auch größere Bodys mit HTTP-Parametern und mehreren Daten zusammenbaut.
    „Meine Komplikation hatte eine Komplikation.“
  • macmoonshine schrieb:

    Da kannst Du mehrere Blöcke mit Daten reinhängen, so wie das die Zeilen 14 bis 18 machen.

    Kann man das so machen?

    Quellcode

    1. NSMutableData *body = [NSMutableData data];
    2. [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    3. [body appendData:[@"Content-Disposition: form-data; name=\"userfile[]\"; filename=\"myImage.jpg\"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    4. [body appendData:[@"Content-Type: application/octet-stream\r\n\r\n"dataUsingEncoding:NSUTF8StringEncoding]];
    5. [body appendData:[NSData dataWithData:imageData]];
    6. [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    7. [body appendData:[@"Content-Disposition: form-data; name=\"userfile[]\"; filename=\"imageZwei.jpg\"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    8. [body appendData:[@"Content-Type: application/octet-stream\r\n\r\n"dataUsingEncoding:NSUTF8StringEncoding]];
    9. [body appendData:[NSData dataWithData:imageZwei]];
    10. [body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    11. [request setHTTPBody:body];
    Alles anzeigen




    Thallius schrieb:

    Bei dem PHP file kannst du übrigens die Tage zählen bis dein Server gehackt wird.

    Was muss ich denn ändern um eine angemessene Sicherheit zu gewähren?

    Das mit dem Überschreiben ist mir natürlich bewusst. :)
  • jonas.e schrieb:

    Was muss ich denn ändern um eine angemessene Sicherheit zu gewähren?

    Angemessene Sicherheit ist „angemessen“, an irgendwelche Vorgaben/Vorstellungen. Diese kenne ich nicht.

    Aber was Du auf jeden Fall machen solltest, nur .jpg erlauben (Serverseitige Prüfung) , sonst hast Du .php .htaccess, .zip mit dabei, die unter Umständen per php mit exec/system aufgerufen werden können.
    Und den Dateinamen einfach so zu übernehmen ist auch nicht gut, da Du den beim Pfadaufbau verwendest (../)
    Ansonsten könnte man sich überlegen, ob man noch eine Authentifizierung und Authorisierung mit einbaut, damit nicht jeder Bilder hochladen kann.

  • entwickler schrieb:

    Aber was Du auf jeden Fall machen solltest, nur .jpg erlauben (Serverseitige Prüfung) , sonst hast Du .php .htaccess, .zip mit dabei, die unter Umständen per php mit exec/system aufgerufen werden können.
    Und den Dateinamen einfach so zu übernehmen ist auch nicht gut, da Du den beim Pfadaufbau verwendest (../)
    Ansonsten könnte man sich überlegen, ob man noch eine Authentifizierung und Authorisierung mit einbaut, damit nicht jeder Bilder hochladen kann.

    Okay, das werde ich auf jeden Fall beachten.
  • jonas.e schrieb:

    macmoonshine schrieb:

    Du solltest auf die Trenner achten, die sind eine beliebte Stolperfalle.

    Was genau meinst du mit Trenner?


    er meint dass "$_FILES['userfile']['name']" zb sowas enthalten könnte "../../../../../etc/hosts". und wo wie du es dann zusammenbaust würde /etc/hosts mit der geuploadeten datei überschrieben.

    es amcht aber auch keinen sinn die dateien mit den vom user definierten filenamen abzulegen sondern sollte den hash des namens verwenden (drauf achten dass nicht bereits einer mit gleichem hash vorhanden ist) oder die dinge eben in eine DB eintragen und eine eindeutige id vergeben welche du dann als dateiname verwendest.
  • gritsch schrieb:

    naja, wenn "imageData" nicht mutable ist dann wird [NSData dataWithData:imageData] einfach wieder imageData zurückgeben - man sollte es sich aber gleich sparen

    Genau das stört mich so unendlich an Objective-C / Cocoa. Apple spezifiziert solche Dinge einfach nicht in der Dokumentation - warum?

    Aber selbst dann bliebe immernoch eine Extra-Kopie :)
    C++
  • zerm schrieb:

    gritsch schrieb:

    naja, wenn "imageData" nicht mutable ist dann wird [NSData dataWithData:imageData] einfach wieder imageData zurückgeben - man sollte es sich aber gleich sparen

    Genau das stört mich so unendlich an Objective-C / Cocoa. Apple spezifiziert solche Dinge einfach nicht in der Dokumentation - warum?

    Aber selbst dann bliebe immernoch eine Extra-Kopie :)


    wozu muss sowas in der doku stehen? davon kann man doch ausgehen denn ein immutable-objekt zu kopieren macht ja keinen sinn. die methode gibt es aber dass du sie verwenden kannst wenn du dir nicht sicher bist ob die data die du hast mutable ist oder nicht. war vor allem praktisch weil man bei copy auch noch ein autorelease dransetzen musst (vor ARC).
  • zerm schrieb:

    Genau das stört mich so unendlich an Objective-C / Cocoa. Apple spezifiziert solche Dinge einfach nicht in der Dokumentation - warum?

    Die Apple-Dokumentation ist eine der umfangreichsten und ausführlichsten Dokumentationen, die ich kenne. Da reichen beispielsweise Android aber auch Boost bei weitem nicht ran.

    Außerdem gibt es zarte Hinweise in initWithData:

    Apple schrieb:

    Return Value
    A data object initialized with the contents data. The returned object might be different than the original receiver.
    „Meine Komplikation hatte eine Komplikation.“
  • macmoonshine schrieb:

    zerm schrieb:

    Genau das stört mich so unendlich an Objective-C / Cocoa. Apple spezifiziert solche Dinge einfach nicht in der Dokumentation - warum?

    Die Apple-Dokumentation ist eine der umfangreichsten und ausführlichsten Dokumentationen, die ich kenne. Da reichen beispielsweise Android aber auch Boost bei weitem nicht ran.

    Außerdem gibt es zarte Hinweise in initWithData:

    Apple schrieb:

    Return Value
    A data object initialized with the contents data. The returned object might be different than the original receiver.


    und noch eine passende aussage in der doku:

    ​Implement NSCopying by retaining the original instead of creating a new copy when the class and its contents are immutable.