Який правильний спосіб POST багаточастинних / форм-даних за допомогою curl?


164

Я використовував цей синтаксис, щоб розмістити файл разом із деякими параметрами:

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

Файл має розмір близько 500K. Перш за все, я бачу, що довжина вмісту повинна бути 254 на стороні передачі. Пізніше довжина вмісту відповіді сервера дорівнює 0. Де я помиляюся?

Ось повний слід команди.

* 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

Відповіді:


254

Наступний синтаксис виправляє це для вас:

curl -v -F key1=value1 -F upload=@localfilename URL

що з Windows & curl.exe?
Пьотр

1
як щодо кількох вкладень?
пекло

8
Він працює точно так само в Windows і.it підтримує кілька "вкладених файлів" / файлів: просто додайте більше -F примірників!
Даніель Стенберг

У цій відповіді є хороший приклад завантаження декількох файлів. stackoverflow.com/questions/11599957 / ...
bmoran

Це працює. на керлі нам не потрібно додавати щось подібне:-H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW'
Емілі

19

щоб завантажити файл за допомогою curl в Windows, я виявив, що шлях вимагає уникнути подвійних лапок

напр

curl -v -F 'upload=@\"C:/myfile.txt\"' URL

1
Ця відповідь мені дуже допомогла. Хоча в моєму випадку я не повинен бігти ", тобто в моєму випадку на Mac я повинен надіслати це як curl -X POST -F key1=value1 -F 'image=@"/Users/ivkremer/Downloads/file name.jpg"';
ivkremer

у моєму випадку - у мене була успішна передача без жодних лапок: curl -v -F file=@/Users/path/to/file/testq.jpg 192.168.0.101:8080/upload-image
chatlanin

У моєму випадку в Windows, я не міг використовувати одиничні лапки, і мені довелося використовувати подвійні лапки на кшталт цієїcurl -F "filename=@\"C:\temp\file.jpg\"" https://someurl.com
Стається


1

Мені важко було надсилати багатоповерховий запит HTTP PUT curlна сервер Java. Я просто спробував

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

і вміст файлу був

-----------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--

але я завжди отримував помилку, що межа була неправильною. Після деякої налагодження Java Backkend я виявив, що реалізація Java додає \r\n--кордон як префікс, тому після зміни мого вхідного файлу на

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

все працює добре!

тл; д-р

Додайте новий рядок (CRLF \r\n) на початку багатостороннього граничного вмісту та --на початку меж та повторіть спробу.

Можливо, ви надсилаєте запит на бекенд Java, який потребує цих змін у межі.


Копіюючи дані POST за допомогою веб-консолі Firefox, я також помітив, що вона використовується \nзамість \r\n. Навіть копію mitmproxy як використовував cURL, \nтому мені довелося копіювати необроблений запит з mitmproxy. З hexdump я бачив, що він використовує шістнадцятковий код 0Aзамість 0D 0A.
baptx

\r\nпотрібно. Подивіться на tools.ietf.org/html/rfc2046#section-5.1.1 стор. 19.
Адам Захран

0

У Windows 10, згорнувшись 7.28.1 в межах shellhell, я виявив, що працює для мене:

$filePath = "c:\temp\dir with spaces\myfile.wav"
$curlPath = ("myfilename=@" + $filePath)
curl -v -F $curlPath URL
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.