Jaki jest właściwy sposób POST multipart / form-data przy użyciu curl?

164

Użyłem tej składni do wysłania pliku wraz z niektórymi parametrami:

curl -v -include --form "key1=value1" --form upload=localfilename URL

Plik ma rozmiar około 500 KB. Przede wszystkim widzę, że długość treści wynosi 254 po stronie nadawczej. Później długość treści odpowiedzi serwera będzie wynosić 0. Gdzie popełniam błąd?

Oto pełny ślad polecenia.

* Couldn't find host xxx.xxx.xxx.xxx in the _netrc file; using defaults
* About to connect() to xxx.xxx.xxx.xxx port yyyy (#0)
*   Trying xxx.xxx.xxx.xxx...
* Adding handle: conn: 0x4b96a0
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x4b96a0) send_pipe: 1, recv_pipe: 0
* Connected to xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx) port yyyy (#0)
* POST /zzzzzz/UploadFile HTTP/1.1
* User-Agent: curl/7.32.0
* Host: xxx.xxx.xxx.xxx:yyyy
* Accept: */*
* Content-Length: 254
* Expect: 100-continue
* Content-Type: multipart/form-data; boundary=------------------------948a6137eef50079
*
* HTTP/1.1 100 Continue
* HTTP/1.1 100 Continue

* HTTP/1.1 200 OK
* HTTP/1.1 200 OK
* Server Apache-Coyote/1.1 is not blacklisted
* Server: Apache-Coyote/1.1
* Server: Apache-Coyote/1.1
* Added cookie JSESSIONID="C1D7DD042E250211D9DEA82688876F88" for domain xxx.xxx.xxx.xxx, path /zzzzz/, expire 0
* Set-Cookie: JSESSIONID=C1D7DD042E250211D9DEA82688876F88; Path=/zzzzzz/;
* HttpOnly
* Set-Cookie: JSESSIONID=C1D7DD042E250211D9DEA82688876F88; Path=/zzzzzz/; HttpOnly
* Content-Type: text/html;charset=ISO-8859-1
Content-Type: text/html;charset=ISO-8859-1
* Content-Length: 0
* Content-Length: 0
* Date: Tue, 01 Oct 2013 11:54:24 GMT
* Date: Tue, 01 Oct 2013 11:54:24 GMT
* Connection #0 to host xxx.xxx.xxx.xxx left intact
Kamalakshi
źródło
możliwy duplikat
użycia

Odpowiedzi:

254

Następująca składnia rozwiązuje to za Ciebie:

curl -v -F key1=value1 -F upload=@localfilename URL
Kamalakshi
źródło
co z systemem Windows i curl.exe?
Piotr
1
a co z wieloma załącznikami?
hellboy
8
Działa dokładnie tak samo w systemie Windows and.it obsługuje wiele „załączników” / plików: wystarczy dodać więcej instancji -F!
Daniel Stenberg,
Ta odpowiedź zawiera dobry przykład przesyłania wielu plików. stackoverflow.com/questions/11599957/ ...
bmoran
To działa. na curl nie musimy dodawać czegoś takiego:-H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW'
Emily
19

aby przesłać plik za pomocą curl w systemie Windows, zauważyłem, że ścieżka wymaga cudzysłowów

na przykład

curl -v -F 'upload=@\"C:/myfile.txt\"' URL
Logan Scott
źródło
1
Ta odpowiedź bardzo mi pomogła. Chociaż w moim przypadku nie powinienem uciekać ", to w moim przypadku na Macu powinienem wysłać to jak curl -X POST -F key1=value1 -F 'image=@"/Users/ivkremer/Downloads/file name.jpg"';
ivkremer
w moim przypadku - pomyślnie przeszedłem transfer bez cudzysłowów: curl -v -F file=@/Users/path/to/file/testq.jpg 192.168.0.101:8080/upload-image
chatlanin
W moim przypadku w systemie Windows nie mogłem użyć pojedynczych cudzysłowów i musiałem użyć takich podwójnych cudzysłowówcurl -F "filename=@\"C:\temp\file.jpg\"" https://someurl.com
Beems
5

To właśnie zadziałało dla mnie

curl -F file=@filename URL
smac89
źródło
1

Miałem trudności z wysłaniem wieloczęściowego żądania HTTP PUT curldo zaplecza Java. Po prostu próbowałem

curl -X PUT URL \
   --header 'Content-Type: multipart/form-data; boundary=---------BOUNDARY' \
   --data-binary @file

a zawartość pliku to

-----------BOUNDARY
Content-Disposition: form-data; name="name1"
Content-Type: application/xml;version=1.0;charset=UTF-8

<xml>content</xml>
-----------BOUNDARY
Content-Disposition: form-data; name="name2"
Content-Type: text/plain

content
-----------BOUNDARY--

ale zawsze otrzymywałem błąd, że granica była nieprawidłowa. Po pewnym debugowaniu zaplecza Javy dowiedziałem się, że implementacja Javy dodawała \r\n--jako przedrostek do granicy, więc po zmianie mojego pliku wejściowego na

                          <-- here's the CRLF
-------------BOUNDARY       <-- added '--' at the beginning
...
-------------BOUNDARY       <-- added '--' at the beginning
...
-------------BOUNDARY--     <-- added '--' at the beginning

wszystko dziala!

tl; dr

Dodaj nową linię (CRLF \r\n) na początku wieloczęściowej zawartości granicy i --na początku granic i spróbuj ponownie.

Może wysyłasz żądanie do zaplecza Java, które potrzebuje tych zmian w granicach.

Lusk116
źródło
Podczas kopiowania danych POST za pomocą konsoli internetowej Firefoksa zauważyłem również, że \nzamiast \r\n. Nawet kopia mitmproxy używana przez cURL, \nwięc musiałem skopiować surowe żądanie za pomocą mitmproxy. Za pomocą zrzutu heksowego zobaczyłem, że 0Azamiast tego używa kodu szesnastkowego 0D 0A.
baptx,
\r\njest wymagane. Zajrzyj na tools.ietf.org/html/rfc2046#section-5.1.1 strona 19.
Adam Zahran
0

W systemie Windows 10, curl 7.28.1 w programie PowerShell, zauważyłem, że działają dla mnie następujące elementy:

$filePath = "c:\temp\dir with spaces\myfile.wav"
$curlPath = ("myfilename=@" + $filePath)
curl -v -F $curlPath URL
Matt
źródło