使用curl来发布多部分/表单数据,文件和许多键值对

时间:2018-12-11 12:21:17

标签: json forms curl post

作为模拟在后端工作时应用程序前端将执行的操作的一部分,我一直在运行各种curl命令。只需将文件作为Content-Type:application/octet-stream发送或将Content-Type:application/json的json发送即可很容易

我与此发送了json内联

curl -X POST -H "Content-Type: application/json" -d '{"username":"xyz","password":"xyz"}' http://127.0.0.1:8088

将json从文件中拉出并发送,如下所示:

curl -X POST -H "Content-Type: application/json" -H 'Accept: application/json' --data-binary @test.json http://127.0.0.1:8088

(没有“接受”功能的任何想法,如果没有它,..,here的解决方案)

仅发送一个文件,如下所示:

curl --request POST -H "Content-Type:application/octet-stream"  --data-binary "@photo.jpg"  http://127.0.0.1:8088

包含json内联和图片的多部分内容非常像这样:

curl --verbose --request POST --header "Content-Type:multipart/form-data" --form key1=value1  --form upload=@photo.jpg   http://127.0.0.1:8088

(来自here的解决方案)

当我尝试从文件和照片中同时提取键值对时,或将json粘贴到curl命令(该命令还上传文件)时,麻烦就开始了。是否可以说服curl"Content-Type:multipart/form-data"发送来自文件和来自文件的文件附件的键值对?

john.json

{
  "surname" : "Doe",
  "name" : "John",
  "city" : "Manchester",
  "address" : "5 Main Street",
  "hobbies" : ["painting","lawnbowls"]
}

john.jpg

我已经尝试了一些方法,但这只会给我错误消息:

尝试内联,粘贴到json中:

$ curl --verbose --request POST --header "Content-Type:multipart/form-data" --data '{"surname" : "Doe","name" : "John","city" : "Manchester","address" : "5 Main Street", "hobbies" : ["painting","lawnbowls"]}'  --form upload=@john.jpg   http://127.0.0.1:8088
Warning: You can only select one HTTP request method! You asked for both POST 
Warning: (-d, --data) and multipart formpost (-F, --form).

然后我试图从文件中同时获取它们,但两者都不喜欢:

$ curl --verbose --request POST --header "Content-Type:multipart/form-data" --form upload@john.json  --form upload=@john.jpg   http://127.0.0.1:8088
Warning: Illegally formatted input field!
curl: option --form: is badly used here
curl: try 'curl --help' or 'curl --manual' for more information

有什么想法可以使这项工作成功吗?

2 个答案:

答案 0 :(得分:1)

我认为您走在正确的道路上,但是看看curl手册页可能会更进一步。

一些密钥从--form选项文档中消失了:

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.

对于JSON,请使用<,对于图片,请使用@

我认为您还应该指定每个部分的内容类型,以帮助Web服务器知道如何解析每个部分。尽管它可能对每个领域都有期望。

You can also tell curl what Content-Type to use by using 'type=', in a manner similar to:

curl -F "web=@index.html;type=text/html" example.com

您必须查找JSON和jpegs的MIME类型。

然后要记住的最后一点:This option can be used multiple times.

大多数内容只是@Tanaike在上面所说的内容的回声,但文档中有更多解释。我建议您进一步阅读。


我认为您的命令最大的抱怨curl是表单的每个部分都有键upload。那有点模棱两可。 JSON有一把钥匙,图片有一把钥匙吗?

了解网络服务器对表单中每个字段的期望也非常重要。文件上传和文本字段之间存在很大差异。

答案 1 :(得分:0)

在@Breedly和@Tanaike的帮助下,以下命令可以正常工作,某人可能会发现它一天有用:

curl --verbose --request POST --header "Content-Type:multipart/form-data" --form "upload1=<john.json" --form "upload2=@john.jpg"  http://127.0.0.1:8088

在这种情况下,很高兴一次"Content-Type:multipart/form-data"覆盖了他们两个。但是,它确实希望json的“ <”而不是“ @”。

以下内容也适用:

curl --verbose --request POST  --form "upload1=<john.json;type=application/json" --form "upload2=@john.jpg;type=multipart/form-data"  http://127.0.0.1:8088