Wie kann ich eine Datei mit `curl` anstelle des Formulars hochladen?

1372
Chuck

Ich habe einen Kunden, dessen Kunde ein Drittanbieter-Clearinghaus verwendet, um Rechnungen zu erhalten. Wir können dies manuell tun, indem wir unsere Daten in XML exportieren, zu einer bestimmten Website gehen und die Datei hochladen. Das entsprechende HTML-Formular sieht folgendermaßen aus:

<form border=0 method="POST" action="/server?request=send" enctype="multipart/form-data" id="uploadform" name="uploadform" onsubmit="return checkUpload()"> <H2>Upload</H2> <p>Server directory:<br> <input type="text" id="directory" name="directory" value="./" size="30"></p> <p>Local file to be uploaded:<br> <input type="file" id="file" name="file" size="40"></p> <p><input type="submit" value="Send"></p> </form> 

Die manuelle Übermittlung über ihre Weboberfläche funktioniert einwandfrei. Ich versuche, ein schnelles Tool zu schreiben, das das Formular für uns verwendet curl. Ich habe viele verschiedene Versuche unternommen, aber bisher wurde jeder als HTML-Antwort "Datei erfolgreich hochgeladen" angezeigt. Die Datei ist leer.

Wir haben anfänglich versucht zu verwenden, curlweil die Clearinghaus-Firma dies vorgeschlagen hatte. Das Beispiel, das sie gaben, war folgendes:

curl -i -k -H "Content-Type:application/octet-stream" \ -d @test.txt -u username:password \ https://example.com/server?request=send?filename=test.txt?directory=DX001 

Als dies nicht funktionierte, schaute ich mir den Code im obigen Formular an und versuchte Folgendes (während er sich im selben Verzeichnis wie die XML-Datei befand):

curl -F "request=send" -F "directory=DX001" -F "file=33823.xml" \ -u username:password -F "enctype=\"multipart/form-data\"" \ -F "id=\"uploadform\"" https://example.com/server 

Wenn das nicht funktionierte, dachte ich, ich würde den absoluten Pfad ausprobieren, obwohl ich im selben Verzeichnis war:

curl -F "request=send" -F "directory=DX001" -F "file=/Users/chuck/Desktop/33823.xml" \ -u username:password -F "enctype=\"multipart/form-data\"" \ -F "id=\"uploadform\"" https://example.com/server 

Jeder einzelne lädt nur eine leere Datei hoch (mit dem angegebenen Dateinamen).

Wie Sie wahrscheinlich dem vollständigen Pfad entnehmen können, mache ich dies von macOS aus, falls dies relevant ist.

Beachten Sie, dass die onsubmitAktion innerhalb des Formulars lediglich sicherstellt, dass weder die directorynoch die fileEingaben leer sind.

0
Es ist wahrscheinlich am besten, sich die Entwicklungstools anzusehen, bevor Sie das Formular manuell senden, wie in [dieser Antwort] vorgeschlagen (https://superuser.com/a/1254742/206587). davidmneedham vor 5 Jahren 1
Ich stimme @davidmneedham vollkommen zu. Senden Sie gute HTTP-Headerfelder. Ihre Webschnittstelle verwendet möglicherweise ein eindeutiges Sitzungscookie (Token). Jerry vor 5 Jahren 0

1 Antwort auf die Frage

2
grawity

Jeder einzelne lädt nur eine leere Datei hoch (mit dem angegebenen Dateinamen).

Curl weiß nicht, welche Felder normaler Text sind und welche Dateien hochgeladen werden. Es geht von der ersteren aus, es sei denn, Sie sagen ausdrücklich, dass sie die Letztere tun soll. Um eine ganze Datei anzuhängen, benötigen Sie das @Präfix:

-F "file=@/Users/chuck/Desktop/33823.xml" 

Sie können dem Server einen anderen Dateinamen geben:

-F "file=@\"/Users/chuck/Desktop/temp.xml\";filename=\"33823.xml\"" 

Der korrekte vollständige Befehl sollte lauten:

curl -u username:password \ -F "directory=DX001" \ -F "file=@/Users/chuck/Desktop/33823.xml" \ https://example.com/server?request=send 

Beachten Sie, wie request=sendes nicht Teil der Formulardaten ist. Es war zuvor Teil der URL und ist jetzt noch Teil der URL. Denken Sie daran, dass Ihre Beispiele zwar alle -uzur Authentifizierung enthalten, jedoch nur für den HTTP-Mechanismus "Basic" und nicht für auf Formularen / Cookies basierende Anmeldeseiten geeignet sind.