curlを使用してmultipart / form-dataを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

回答:


254

次の構文で修正されます。

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

Windows&curl.exeはどうですか?
ピオトル2015

1
複数の添付ファイルはどうですか?
hellboy 2015年

8
これはWindowsでもまったく同じように機能し、複数の「添付ファイル」/ファイルをサポートします。-Fインスタンスを追加するだけです!
Daniel Stenberg 2016年

この回答は、複数のファイルをアップロードする良い例です。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

5

これは私のために働いたものです

curl -F file=@filename URL

1

マルチパートHTTP PUTリクエストをcurlJavaバックエンドに送信するのに苦労しました。私は単に試しました

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

\r\nマルチパート境界コンテンツ--の先頭と境界の先頭に改行(CRLF )を追加して、再試行してください。

境界でこの変更を必要とするJavaバックエンドにリクエストを送信している可能性があります。


Firefox WebコンソールでPOSTデータをコピーすると、の\n代わりにが使用されていることにも気付きました\r\n。cURLが使用\nしていたmitmproxyコピーでさえ、私は未加工のリクエストをmitmproxyでコピーする必要がありました。hexdumpで、の0A代わりに16進コードを使用していることがわかりました0D 0A
baptx

これ\r\nは必須です。見てくださいtools.ietf.org/html/rfc2046#section-5.1.1ページ19
アダムZahran

0

Windows 10では、PowerShell内のcurl 7.28.1で、次のことが機能することがわかりました。

$filePath = "c:\temp\dir with spaces\myfile.wav"
$curlPath = ("myfilename=@" + $filePath)
curl -v -F $curlPath URL
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.