使用curl发布POST多部分/表单数据的正确方法是什么?


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

Answers:


254

以下语法为您解决了该问题:

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

Windows&curl.exe呢?
Piotr

1
多个附件呢?
hellboy

8
它在Windows上的工作原理完全相同,并且它支持多个“附件” /文件:只需添加更多-F实例!
Daniel Stenberg

这个答案有一个上传多个文件的好例子。stackoverflow.com/questions/11599957/…–
bmoran

这可行。卷曲时,我们不需要添加以下内容:-H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW'
艾米莉·

19

在Windows中使用curl上传文件,我发现该路径需要转义的双引号

例如

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


1

我很难向curlJava后端发送多部分HTTP PUT请求。我只是尝试

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后端调试之后,我发现Java实现向\r\n--边界添加了前缀a,因此将输入文件更改为

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

一切正常!

tl; dr

\r\n在多部分边界内容--的开头和边界的开头添加换行符(CRLF ),然后重试。

也许您正在向Java后端发送请求,该请求需要在边界中进行此更改。


当使用Firefox Web控制台复制POST数据时,我还注意到它正在使用\n而不是\r\n。即使使用cURL进行mitmproxy复制,\n因此我也必须使用mitmproxy复制原始请求。我通过hexdump看到它正在使用hex代码0A而不是0D 0A
baptx '19

\r\n是必需的。看看tools.ietf.org/html/rfc2046#section-5.1.1第19页
亚当赫兰

0

在Windows 10上的powershell中卷曲7.28.1,我发现以下对我有用:

$filePath = "c:\temp\dir with spaces\myfile.wav"
$curlPath = ("myfilename=@" + $filePath)
curl -v -F $curlPath URL
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.