วิธีที่ถูกต้องในการ POST multipart / form-data โดยใช้ 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
Piotr

1
แล้วหลาย ๆ ไฟล์แนบล่ะ?
hellboy

8
มันทำงานเหมือนกันทุกอย่างบน Windows และมันรองรับ "ไฟล์แนบ" / ไฟล์หลายไฟล์: เพียงเพิ่มอินสแตนซ์ -F เพิ่มเติม!
Daniel Stenberg

คำตอบนี้มีตัวอย่างที่ดีในการอัปโหลดหลายไฟล์ stackoverflow.com/questions/11599957/…
bmoran

วิธีนี้ใช้ได้ผล ในขดเราไม่จำเป็นต้องเพิ่มบางสิ่งเช่นนี้:-H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW'
Emily

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
Beems


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 แบ็คเอนด์บางส่วนฉันพบว่าการใช้งาน Java ได้เพิ่ม\r\n--คำนำหน้าให้กับขอบเขตดังนั้นหลังจากเปลี่ยนไฟล์อินพุตของฉันเป็น

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

ทุกอย่างทำงานได้ดี!

TL; DR

เพิ่ม newline (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
Adam Zahran

0

ใน Windows 10, curl 7.28.1 ภายใน powershell ฉันพบสิ่งต่อไปนี้สำหรับฉัน:

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