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

lztngnrs  于 2022-11-13  发布在  其他
关注(0)|答案(7)|浏览(223)

我使用以下语法发布了一个沿着一些参数的文件:

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
mmvthczy

mmvthczy1#

以下语法可为您修复此问题:

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

x6h2sr282#

在Windows中使用curl上传文件时,我发现路径需要转义双引号
例如:

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

h9vpoimq3#

这对我很有效

curl --form file='@filename' URL

当我给出这个答案的时候(*4年多以前 *),我似乎并不真正理解这个问题,也不理解表单字段是如何工作的。我只是根据我在不同场景中尝试过的内容来回答,它对我很有效。
首先,OP犯的唯一错误是没有在文件名前使用@符号。其次,我使用file=...的答案只对我有效,因为我试图上传的表单字段名为file。如果您的表单字段名为其他名称,请使用该名称。

说明

curlmanpages;在选项--form的说明下,它说:
这样可以上传二进制文件等。要强制“内容”部分为文件,请在文件名前加上@符号。要只从文件中获取内容部分,请在文件名前加上符号〈。@和〈之间的区别在于,@使文件作为文件上传附加在帖子中。而〈创建一个文本字段,并从文件中获取该文本字段的内容。
如果您尝试进行表单上传,您很可能希望使用@前缀来上传文件,而不是使用<来上传文件的 * 内容 *。

附录

现在我还必须补充一点,必须小心使用<符号,因为在大多数unix shell中,<是输入重定向符号 [巧合的是,它也会在<之前将给定文件的内容提供给程序的命令标准输入]。这意味着,如果您没有正确地转义该符号或将其用引号括起来,您可能会发现curl命令的行为与您预期的不同。
同样,我还建议引用@符号。
您可能还对另一个问题感兴趣,该问题的标题为:application/x-www-form-urlencoded or multipart/form-data?
我这么说是因为curl提供了其他上传文件的方法,但是它们在头文件中设置的内容类型不同。例如,--data选项提供了一种类似的机制,将文件作为数据上传,但是使用了不同的内容类型。
无论如何,这就是我想说的关于这个答案的一切,因为它开始得到更多的赞成票。我希望这有助于消除任何混淆,如这个答案和accepted答案之间的区别。除了这个解释,真的没有什么。

2j4z5cfb

2j4z5cfb4#

我很难向Java后端发送一个包含curl的多部分HTTPPUT请求。

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--作为前缀,所以在将我的输入文件更改为

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

一切正常!

tl;医生

请在多部分边界内容的开头添加换行符(CRLF \r\n),并在边界的开头添加--,然后重试。
也许您正在向Java后端发送一个请求,该后端需要边界中的这些更改。

o75abkj4

o75abkj45#

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

$filePath = "c:\temp\dir with spaces\myfile.wav"
$curlPath = ("myfilename=@" + $filePath)
curl -v -F $curlPath URL
qeeaahzv

qeeaahzv6#

使用Smartbear Zephyr秤(服务器版本),您可以通过以下方式将文件附加到测试循环:

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"

(返回{“id”:7099})

file2.txt中的位置:测试周期还具有指向测试计划的链接和指向问题的链接。

{
  "projectKey": "TDD",
  "testPlanKey": "TDD-P1",
  "name": "Bonjour chez vous, Le Prisonnier",
  "issueKey": "TDLT-999"
  }

我在这里发帖,因为我无法从官方文件中找到答案:)

fjaof16o

fjaof16o7#

也许这种形式行得通
“内容类型:应用程序/x-www-form-url编码”

相关问题