[英]What is the right way to POST multipart/form-data using curl?
I used this syntax to post a file along with some parameters:我使用这种语法来发布一个文件以及一些参数:
curl -v -include --form "key1=value1" --form upload=localfilename URL
The file is around 500K in size.该文件大小约为 500K。 First of all, I see content length to be 254 on the transmit side.首先,我看到传输端的内容长度为 254。 Later the server response's content length is 0. Where am I going wrong?后来服务器响应的内容长度为0。我哪里出错了?
Here is the complete trace of the command.这是命令的完整跟踪。
* 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
以下语法为您修复它:
curl -v -F key1=value1 -F upload=@localfilename URL
to upload a file using curl in Windows I found that the path requires escaped double quotes在 Windows 中使用 curl 上传文件我发现路径需要转义双引号
eg例如
curl -v -F 'upload=@\"C:/myfile.txt\"' URL
This is what worked for me这对我有用
curl --form file='@filename' URL
It seems when I gave this answer ( 4+ years ago ), I didn't really understand the question, or how form fields worked.似乎当我给出这个答案时( 4 年多以前),我并没有真正理解这个问题,或者表单字段是如何工作的。 I was just answering based on what I had tried in a difference scenario, and it worked for me.我只是根据我在不同场景中的尝试来回答,它对我有用。
So firstly, the only mistake the OP made was in not using the @
symbol before the file name.所以首先,OP 犯的唯一错误是没有在文件名前使用@
符号。 Secondly, my answer which uses file=...
only worked for me because the form field I was trying to do the upload for was called file
.其次,我使用file=...
答案只对我有用,因为我尝试上传的表单字段被称为file
。 If your form field is called something else, use that name instead.如果您的表单字段被称为其他名称,请改用该名称。
From the curl
manpages ;来自curl
联机帮助页; under the description for the option --form
it says:在选项--form
的描述下,它说:
This enables uploading of binary files etc. To force the 'content' part to be a file, prefix the file name with an @ sign.这允许上传二进制文件等。要强制“内容”部分成为文件,请在文件名前加上 @ 符号。 To just get the content part from a file, prefix the file name with the symbol <.要仅从文件中获取内容部分,请在文件名前加上符号 <。 The difference between @ and < is then that @ makes a file get attached in the post as a file upload, while the < makes a text field and just get the contents for that text field from a file. @ 和 < 之间的区别在于 @ 使文件作为文件上传附加到帖子中,而 < 生成文本字段并仅从文件中获取该文本字段的内容。
Chances are that if you are trying to do a form upload, you will most likely want to use the @
prefix to upload the file rather than <
which uploads the contents of the file.很有可能,如果您尝试进行表单上传,您很可能希望使用@
前缀上传文件,而不是<
上传文件的内容。
Now I must also add that one must be careful with using the <
symbol because in most unix shells, <
is the input redirection symbol [which coincidentally will also supply the contents of the given file to the command standard input of the program before <
] .现在我还必须补充一点,使用<
符号时必须小心,因为在大多数 unix shell 中, <
是输入重定向符号[巧合的是,它也会在<
之前将给定文件的内容提供给程序的命令标准输入] . This means that if you do not properly escape that symbol or wrap it in quotes, you may find that your curl
command does not behave the way you expect.这意味着,如果您没有正确地转义该符号或将其包裹在引号中,您可能会发现curl
命令的行为与您期望的方式不同。
On that same note, I will also recommend quoting the @
symbol.同样,我还建议引用@
符号。
You may also be interested in this other question titled: application/x-www-form-urlencoded or multipart/form-data?您可能还对另一个问题感兴趣: application/x-www-form-urlencoded 或 multipart/form-data?
I say this because curl
offers other ways of uploading a file, but they differ in the content-type set in the header.我这样说是因为curl
提供了其他上传文件的方法,但它们在标题中设置的内容类型不同。 For example the --data
option offers a similar mechanism for uploading files as data, but uses a different content-type for the upload.例如,-- --data
选项提供了一种类似的将文件作为数据上传的机制,但使用不同的内容类型进行上传。
Anyways that's all I wanted to say about this answer since it started to get more upvotes.无论如何,这就是我想说的关于这个答案的全部内容,因为它开始获得更多的支持。 I hope this helps erase any confusions such as the difference between this answer and the accepted answer.我希望这有助于消除任何混淆,例如此答案与已接受答案之间的差异。 There is really none, except for this explanation.真的没有,除了这个解释。
I had a hard time sending a multipart HTTP PUT request with curl
to a Java backend.我很难将带有curl
的多部分 HTTP PUT 请求发送到 Java 后端。 I simply tried我只是试过
curl -X PUT URL \
--header 'Content-Type: multipart/form-data; boundary=---------BOUNDARY' \
--data-binary @file
and the content of the file was并且文件的内容是
-----------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--
but I always got an error that the boundary was incorrect.但我总是收到一个错误,说边界不正确。 After some Java backend debugging I found out that the Java implementation was adding a \\r\\n--
as a prefix to the boundary, so after changing my input file to经过一些 Java 后端调试后,我发现 Java 实现添加了一个\\r\\n--
作为边界的前缀,因此在将我的输入文件更改为
<-- here's the CRLF
-------------BOUNDARY <-- added '--' at the beginning
...
-------------BOUNDARY <-- added '--' at the beginning
...
-------------BOUNDARY-- <-- added '--' at the beginning
everything works fine!一切正常!
Add a newline (CRLF \\r\\n
) at the beginning of the multipart boundary content and --
at the beginning of the boundaries and try again.在多部分边界内容的开头和--
在边界的开头添加换行符 (CRLF \\r\\n
),然后重试。
Maybe you are sending a request to a Java backend that needs this changes in the boundary.也许您正在向需要边界更改的 Java 后端发送请求。
On Windows 10, curl 7.28.1 within powershell, I found the following to work for me:在 Windows 10 上,powershell 中的 curl 7.28.1,我发现以下内容对我有用:
$filePath = "c:\temp\dir with spaces\myfile.wav"
$curlPath = ("myfilename=@" + $filePath)
curl -v -F $curlPath URL
Maybe this form work也许这种形式有效
curl -X POST -d 'key1=value1&key2=value2' http://URL -H "Content-Type: application/x-www-form-urlencoded" curl -X POST -d 'key1=value1&key2=value2' http://URL -H "Content-Type: application/x-www-form-urlencoded"
With Smartbear Zephyr Scale, server version, you would attach a file to a Test Cycle this way:使用 Smartbear Zephyr Scale,服务器版本,您可以通过以下方式将文件附加到测试周期:
curl -H "Authorization: Basic YkskfdygyzghhMg==" -X POST -H "Content-Type: multipart/form-data" https://jira/jira/rest/atm/1.0/testrun/TDLT-C32/attachments --form file="@file2.txt"
(returns {"id":7099}) (返回 {"id":7099})
where in file2.txt: Test Cycle has also a link to a test plan, and a link to an issue.在 file2.txt 中的位置:测试周期还有一个指向测试计划的链接和一个指向问题的链接。
{
"projectKey": "TDD",
"testPlanKey": "TDD-P1",
"name": "Bonjour chez vous, Le Prisonnier",
"issueKey": "TDLT-999"
}
I'm posting this since unable to find that out from official documentation:)我发布这个是因为无法从官方文档中找到它:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.