575 Stimmen

Verwendung von cURL zum Hochladen von POST-Daten mit Dateien

Ich möchte cURL verwenden, um nicht nur Datenparameter in HTTP POST zu senden, sondern auch Dateien mit bestimmten Formularnamen hochzuladen. Wie soll ich das anstellen?

HTTP-Post-Parameter:

Benutzerkennung = 12345 filecomment = Dies ist eine Bilddatei

HTTP Datei-Upload: Dateispeicherort = /home/user1/Desktop/test.jpg Formularname für die Datei = image (entspricht dem $_FILES['image'] auf der PHP-Seite)

Ich habe mir einen Teil des cURL-Befehls wie folgt vorgestellt:

curl -d "userid=1&filecomment=This is an image file" --data-binary @"/home/user1/Desktop/test.jpg" localhost/uploader.php

Das Problem, das sich mir stellt, ist folgendes:

Notice: Undefined index: image in /var/www/uploader.php

Das Problem ist, dass ich $_FILES['image'] verwende, um Dateien im PHP-Skript abzuholen.

Wie kann ich meine cURL-Befehle entsprechend anpassen?

839voto

jimp Punkte 16393

Sie müssen die -F Option:
-F/--form <name=content> Specify HTTP multipart POST data (H)

Versuchen Sie dies:

curl \
  -F "userid=1" \
  -F "filecomment=This is an image file" \
  -F "image=@/home/user1/Desktop/test.jpg" \
  localhost/uploader.php

155voto

r1ckr Punkte 5573

Abfangen der Benutzerkennung als Pfadvariable (empfohlen):

curl -i -X POST -H "Content-Type: multipart/form-data" 
-F "data=@test.mp3" http://mysuperserver/media/1234/upload/

Erfassen der Benutzerkennung als Teil des Formulars:

curl -i -X POST -H "Content-Type: multipart/form-data" 
-F "data=@test.mp3;userid=1234" http://mysuperserver/media/upload/

o:

curl -i -X POST -H "Content-Type: multipart/form-data" 
-F "data=@test.mp3" -F "userid=1234" http://mysuperserver/media/upload/

27voto

KARTHIKEYAN.A Punkte 14230

Wenn Sie eine Binärdatei wie z. B. csv hochladen, verwenden Sie das folgende Format zum Hochladen der Datei

curl -X POST \
    'http://localhost:8080/workers' \
    -H 'authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6ImFjY2VzcyIsInR5cGUiOiJhY2Nlc3MifQ.eyJ1c2VySWQiOjEsImFjY291bnRJZCI6MSwiaWF0IjoxNTExMzMwMzg5LCJleHAiOjE1MTM5MjIzODksImF1ZCI6Imh0dHBzOi8veW91cmRvbWFpbi5jb20iLCJpc3MiOiJmZWF0aGVycyIsInN1YiI6ImFub255bW91cyJ9.HWk7qJ0uK6SEi8qSeeB6-TGslDlZOTpG51U6kVi8nYc' \
    -H 'content-type: application/x-www-form-urlencoded' \
    --data-binary '@/home/limitless/Downloads/iRoute Masters - Workers.csv'

24voto

Libertese Punkte 249

Hier ist meine Lösung, ich habe viele Beiträge gelesen und sie waren wirklich hilfreich. Schließlich schrieb ich einige Code für kleine Dateien, mit cURL und PHP, dass ich denke, seine wirklich nützlich.

public function postFile()
{    
        $file_url = "test.txt";  //here is the file route, in this case is on same directory but you can set URL too like "http://examplewebsite.com/test.txt"
        $eol = "\r\n"; //default line-break for mime type
        $BOUNDARY = md5(time()); //random boundaryid, is a separator for each param on my post curl function
        $BODY=""; //init my curl body
        $BODY.= '--'.$BOUNDARY. $eol; //start param header
        $BODY .= 'Content-Disposition: form-data; name="sometext"' . $eol . $eol; // last Content with 2 $eol, in this case is only 1 content.
        $BODY .= "Some Data" . $eol;//param data in this case is a simple post data and 1 $eol for the end of the data
        $BODY.= '--'.$BOUNDARY. $eol; // start 2nd param,
        $BODY.= 'Content-Disposition: form-data; name="somefile"; filename="test.txt"'. $eol ; //first Content data for post file, remember you only put 1 when you are going to add more Contents, and 2 on the last, to close the Content Instance
        $BODY.= 'Content-Type: application/octet-stream' . $eol; //Same before row
        $BODY.= 'Content-Transfer-Encoding: base64' . $eol . $eol; // we put the last Content and 2 $eol,
        $BODY.= chunk_split(base64_encode(file_get_contents($file_url))) . $eol; // we write the Base64 File Content and the $eol to finish the data,
        $BODY.= '--'.$BOUNDARY .'--' . $eol. $eol; // we close the param and the post width "--" and 2 $eol at the end of our boundary header.

        $ch = curl_init(); //init curl
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
                         'X_PARAM_TOKEN : 71e2cb8b-42b7-4bf0-b2e8-53fbd2f578f9' //custom header for my api validation you can get it from $_SERVER["HTTP_X_PARAM_TOKEN"] variable
                         ,"Content-Type: multipart/form-data; boundary=".$BOUNDARY) //setting our mime type for make it work on $_FILE variable
                    );
        curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/1.0 (Windows NT 6.1; WOW64; rv:28.0) Gecko/20100101 Firefox/28.0'); //setting our user agent
        curl_setopt($ch, CURLOPT_URL, "api.endpoint.post"); //setting our api post url
        curl_setopt($ch, CURLOPT_COOKIEJAR, $BOUNDARY.'.txt'); //saving cookies just in case we want
        curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1); // call return content
        curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, 1); navigate the endpoint
        curl_setopt($ch, CURLOPT_POST, true); //set as post
        curl_setopt($ch, CURLOPT_POSTFIELDS, $BODY); // set our $BODY 

        $response = curl_exec($ch); // start curl navigation

     print_r($response); //print response

}

Damit sollten wir auf dem "api.endpoint.post" die folgenden Var's gebucht bekommen. Sie können leicht mit diesem Skript testen, und Sie sollten diese Debugs auf die Funktion erhalten werden postFile() in der letzten Zeile.

print_r($response); //print response

public function getPostFile()
{

    echo "\n\n_SERVER\n";
    echo "<pre>";
    print_r($_SERVER['HTTP_X_PARAM_TOKEN']);
    echo "/<pre>";
    echo "_POST\n";
    echo "<pre>";
    print_r($_POST['sometext']);
    echo "/<pre>";
    echo "_FILES\n";
    echo "<pre>";
    print_r($_FILEST['somefile']);
    echo "/<pre>";
}

Es sollte gut funktionieren, es mag bessere Lösungen geben, aber dies funktioniert und ist wirklich hilfreich, um zu verstehen, wie die Boundary und multipart/from-data Mime auf PHP und cURL-Bibliothek funktioniert.

13voto

Evandro Pomatti Punkte 10230

Nach vielen Versuchen hat dieser Befehl bei mir funktioniert:

curl -v -F filename=image.jpg -F upload=@image.jpg http://localhost:8080/api/upload

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X