提问人:kamaci 提问时间:8/24/2011 最后编辑:Peter Mortensenkamaci 更新时间:9/10/2023 访问量:4136244
如何使用 cURL 发布 json 数据?
How do I POST JSON data with cURL?
问:
我使用 Ubuntu 并在其上安装了 cURL。我想使用 cURL 测试我的 Spring REST 应用程序。我在 Java 端编写了我的 POST 代码。但是,我想用cURL测试它。我正在尝试发布JSON数据。示例数据如下所示:
{"value":"30","type":"Tip 3","targetModule":"Target 3","configurationGroup":null,"name":"Configuration Deneme 3","description":null,"identity":"Configuration Deneme 3","version":0,"systemId":3,"active":true}
我使用这个命令:
curl -i \
-H "Accept: application/json" \
-H "X-HTTP-Method-Override: PUT" \
-X POST -d "value":"30","type":"Tip 3","targetModule":"Target 3","configurationGroup":null,"name":"Configuration Deneme 3","description":null,"identity":"Configuration Deneme 3","version":0,"systemId":3,"active":true \
http://localhost:8080/xx/xxx/xxxx
它返回以下错误:
HTTP/1.1 415 Unsupported Media Type
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=utf-8
Content-Length: 1051
Date: Wed, 24 Aug 2011 08:50:17 GMT
错误描述如下:
服务器拒绝了此请求,因为请求实体的格式不受所请求方法 () 的请求资源支持。
Tomcat 日志: “发布 /ui/webapp/conf/clear HTTP/1.1” 415 1051
cURL 命令的正确格式是什么?
这是我的 Java 端代码(我已经测试了 GET 和 DELETE,它们有效):PUT
@RequestMapping(method = RequestMethod.PUT)
public Configuration updateConfiguration(HttpServletResponse response, @RequestBody Configuration configuration) { //consider @Valid tag
configuration.setName("PUT worked");
//todo If error occurs response.sendError(HttpServletResponse.SC_NOT_FOUND);
return configuration;
}
答:
您需要将 content-type 设置为 application/json。但是 -d
(or ) 默认发送 Content-Type,Spring 方面不接受它。--data
application/x-www-form-urlencoded
查看 curl 手册页,我认为您可以使用 -H
(或):--header
-H "Content-Type: application/json"
完整示例:
curl --header "Content-Type: application/json" \
--request POST \
--data '{"username":"xyz","password":"xyz"}' \
http://localhost:3000/api/login
(-H
是 的缩写 , for--header
-d
--data
)
请注意,如果使用 ,则这是可选的,因为该标志表示 POST 请求。-request POST
-d
-d
在 Windows 上,情况略有不同。请参阅评论线程。
评论
curl -X POST -H "Content-Type: application/json" -d "{ \"key1\": \"value1\" }" http://localhost:3000/api/method
"{ """key1""": """value1""" }"
"Content-Type: application/json"
"application/json"
尝试将您的数据放入文件中,然后使用body.json
curl -H "Content-Type: application/json" --data @body.json http://localhost:8080/ui/webapp/conf
评论
--data-binary
--data
--data
@
我只是遇到了同样的问题。我可以通过指定
-H "Content-Type: application/json; charset=UTF-8"
你可能会发现 resty 很有用:
它是一个包装轮的 CURL,它简化了命令行 REST 请求。你把它指向你的 API 端点,它会给你 PUT 和 POST 命令(示例改编自主页)。
resty http://127.0.0.1:8080/data #Sets up resty to point at your endpoing
GET /blogs.json #Gets http://127.0.0.1:8080/data/blogs.json
#Put JSON
PUT /blogs/2.json '{"id" : 2, "title" : "updated post", "body" : "This is the new."}'
# POST JSON from a file
POST /blogs/5.json < /tmp/blog.json
此外,通常仍需要添加内容类型标头。但是,您可以执行此操作一次,以设置默认值,即按方法按站点添加配置文件: 设置默认的 RESTY 选项
它对我有用:
curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"id":100}' http://localhost/api/postJsonReader.do
它愉快地映射到 Spring 控制器:
@RequestMapping(value = "/postJsonReader", method = RequestMethod.POST)
public @ResponseBody String processPostJsonData(@RequestBody IdOnly idOnly) throws Exception {
logger.debug("JsonReaderController hit! Reading JSON data!"+idOnly.getId());
return "JSON Received";
}
IdOnly
是具有 id 属性的简单 POJO。
这对我来说效果很好,另外还使用了 BASIC 身份验证:
curl -v --proxy '' --basic -u Administrator:password -X POST -H "Content-Type: application/json"
--data-binary '{"value":"30","type":"Tip 3","targetModule":"Target 3","configurationGroup":null,"name":"Configuration Deneme 3","description":null,"identity":"Configuration Deneme 3","version":0,"systemId":3,"active":true}'
http://httpbin.org/post
当然,您永远不应该在没有SSL和检查证书的情况下使用BASIC身份验证。
我今天再次遇到这个问题,使用 Cygwin 的 cURL 7.49.1 for Windows......当使用或与 JSON 参数一起使用时,cURL 会感到困惑,并将 JSON 中的参数解释为 URL 模板。添加一个参数来关闭 cURL 通配解决了这个问题。--data
--data-binary
{}
-g
另请参阅传递带有括号的 URL 以进行 curl。
我正在使用以下格式在Web服务器上进行测试。
use -F 'json data'
让我们假设这个 JSON 字典格式:
{
'comment': {
'who':'some_one',
'desc' : 'get it'
}
}
完整示例
curl -XPOST your_address/api -F comment='{"who":"some_one", "desc":"get it"}'
评论
如果要针对 RESTful 接口测试大量 JSON 发送/响应,可能需要查看适用于 Chrome 的 Postman 插件(允许您手动定义 Web 服务测试)及其基于 Node.js 的 Newman 命令行伴侣(允许您针对 Postman 测试的“集合”自动执行测试)。既免费又开放!
对于 Windows,使用单引号表示值对我不起作用,但在更改为双引号后确实有效。此外,我需要转义大括号内的双引号。-d
也就是说,以下操作不起作用:
curl -i -X POST -H "Content-Type: application/json" -d '{"key":"val"}' http://localhost:8080/appname/path
但以下方法奏效了:
curl -i -X POST -H "Content-Type: application/json" -d "{\"key\":\"val\"}" http://localhost:8080/appname/path
评论
Enable-ExperimentalFeature PSNativeCommandArgumentPassing
使用 CURL Windows,请尝试以下操作:
curl -X POST -H "Content-Type:application/json" -d "{\"firstName\": \"blablabla\",\"lastName\": \"dummy\",\"id\": \"123456\"}" http-host/_ah/api/employeeendpoint/v1/employee
这对我来说效果很好。
curl -X POST --data @json_out.txt http://localhost:8080/
哪里
-X
表示 HTTP 谓词。
--data
表示要发送的数据。
评论
-X POST
--data
-d
例如,创建一个 JSON 文件,params.json,并将以下内容添加到其中:
[
{
"environment": "Devel",
"description": "Machine for test, please do not delete!"
}
]
然后运行以下命令:
curl -v -H "Content-Type: application/json" -X POST --data @params.json -u your_username:your_password http://localhost:8000/env/add_server
评论
~/.curlrc
--header Content-Type:Application/JSON
这对我有用:
curl -H "Content-Type: application/json" -X POST -d @./my_json_body.txt http://192.168.1.1/json
您还可以将 JSON 内容放入文件中,并通过标准输入使用该选项将其传递给 curl,如下所示:--upload-file
echo 'my.awesome.json.function({"do" : "whatever"})' | curl -X POST "http://url" -T -
您可以使用 Postman 及其直观的 GUI 来组装您的命令。cURL
- 安装并启动 Postman
- 输入您的 URL、帖子正文、请求标头等。
- 点击
Code
- 从下拉列表中选择
cURL
- 复制并粘贴您的命令
cURL
注意:下拉列表中有几个自动生成请求的选项,这就是为什么我认为我的帖子首先是必要的。
评论
HTTPie 是一个推荐的替代方案,因为你可以只做curl
http POST http://example.com/some/endpoint name=value name1=value1
默认情况下,它使用 JSON,并将为您设置必要的标头,并将数据编码为有效的 JSON。还有:
Some-Header:value
对于标头,以及
name==value
用于查询字符串参数。如果你有大量的数据,你也可以从文件中读取它,让它进行JSON编码:
[email protected]
评论
httpie
curl
httpie
使用 -d 选项添加有效负载
curl -X POST \
http://<host>:<port>/<path> \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"foo": "bar",
"lorem": "ipsum"
}'
另外:
使用 -X POST 使用 POST 方法
使用 -H 'Accept: application/json' 添加 accept 类型标头
使用 -H 'Content-Type: application/json' 添加内容类型标头
评论
curl
-v
为此,我制作了一个名为fetcher的工具。它可以发送请求并格式化 curl 片段:
下面是一个示例:
输出示例:
curl -XGET -H "Accept: application/json" -d "{\"value\":\"30\",\"type\":\"Tip 3\",\"targetModule\":\"Target 3\",\"configurationGroup\":null,\"name\":\"Configuration Deneme 3\",\"description\":null,\"identity\":\"Configuration Deneme 3\",\"version\":0,\"systemId\":3,\"active\":true}" "http://localhost:8080/xx/xxx/xxxx"
评论
您可以使用 Postman 转换为 CURL:
注意:
最新的 Postman 版本有一些 UI 升级,现在代码链接在侧边栏中可用。
评论
这在 Windows 10 上对我有用:
curl -d "{"""owner""":"""sasdasdasdasd"""}" -H "Content-Type: application/json" -X PUT http://localhost:8080/api/changeowner/CAR4
这是另一种方法,如果你要包含动态数据。
#!/bin/bash
version=$1
text=$2
branch=$(git rev-parse --abbrev-ref HEAD)
repo_full_name=$(git config --get remote.origin.url | sed 's/.*:\/\/github.com\///;s/.git$//')
token=$(git config --global github.token)
generate_post_data()
{
cat <<EOF
{
"tag_name": "$version",
"target_commitish": "$branch",
"name": "$version",
"body": "$text",
"draft": false,
"prerelease": false
}
EOF
}
echo "Create release $version for repo: $repo_full_name branch: $branch"
curl --data "$(generate_post_data)" "https://api.github.com/repos/$repo_full_name/releases?access_token=$token"
我遇到了以下问题:
curl -X POST http://your-server-end-point -H “内容类型:application/json” -d @path-of-your-json-file.json
看,我做的一切都是对的。只有一件事 - 我在 JSON 文件路径之前错过了“@”。
我在 Internet 上找到了一个相关的首选文档 - Common Options。
根据 Anand Rockzz 的回答,以下是我在 GitHub Actions 上对此所做的工作。由于标签的原因,这有点棘手。EOF
我的目标是在 Vercel 部署完成后发送 HTTP 调用(类似于 webhook)。
这个真实世界的例子可能会帮助其他人。
send-webhook-callback-once-deployment-ready:
name: Invoke webhook callback url defined by the customer (Ubuntu 18.04)
runs-on: ubuntu-18.04
needs: await-for-vercel-deployment
steps:
- uses: actions/checkout@v1 # Get last commit pushed - See https://github.com/actions/checkout
- name: Expose GitHub slug/short variables # See https://github.com/rlespinasse/github-slug-action#exposed-github-environment-variables
uses: rlespinasse/[email protected] # See https://github.com/rlespinasse/github-slug-action
- name: Expose git environment variables and call webhook (if provided)
# Workflow overview:
# - Resolves webhook url from customer config file
# - If a webhook url was defined, send a
run: |
MANUAL_TRIGGER_CUSTOMER="${{ github.event.inputs.customer}}"
CUSTOMER_REF_TO_DEPLOY="${MANUAL_TRIGGER_CUSTOMER:-$(cat vercel.json | jq --raw-output '.build.env.NEXT_PUBLIC_CUSTOMER_REF')}"
VERCEL_DEPLOYMENT_COMPLETED_WEBHOOK=$(cat vercel.$CUSTOMER_REF_TO_DEPLOY.staging.json | jq --raw-output '.build.env.VERCEL_DEPLOYMENT_COMPLETED_WEBHOOK')
# Checking if a webhook url is defined
if [ -n "$VERCEL_DEPLOYMENT_COMPLETED_WEBHOOK" ]; then
# Run script that populates git-related variables as ENV variables
echo "Running script populate-git-env.sh"
. ./scripts/populate-git-env.sh
echo "Resolved git variables:"
echo "'GIT_COMMIT_SHA': $GIT_COMMIT_SHA"
echo "'GIT_COMMIT_REF': $GIT_COMMIT_REF"
echo "'GIT_COMMIT_TAGS': $GIT_COMMIT_TAGS"
# Generates JSON using a bash function - See https://stackoverflow.com/a/57369772/2391795
# "End Of File" must be at the beginning of the line with no space/tab before or after - See https://stackoverflow.com/a/12909284/2391795
# But, when executed by GitHub Action, it must be inside the "run" section instead
generate_post_data() {
cat <<EOF
{
"MANUAL_TRIGGER_CUSTOMER": "${MANUAL_TRIGGER_CUSTOMER}",
"CUSTOMER_REF": "${CUSTOMER_REF_TO_DEPLOY}",
"STAGE": "staging",
"GIT_COMMIT_SHA": "${GIT_COMMIT_SHA}",
"GIT_COMMIT_REF": "${GIT_COMMIT_REF}",
"GIT_COMMIT_TAGS": "${GIT_COMMIT_TAGS}",
"GITHUB_REF_SLUG": "${GITHUB_REF_SLUG}",
"GITHUB_HEAD_REF_SLUG": "${GITHUB_HEAD_REF_SLUG}",
"GITHUB_BASE_REF_SLUG": "${GITHUB_BASE_REF_SLUG}",
"GITHUB_EVENT_REF_SLUG": "${GITHUB_EVENT_REF_SLUG}",
"GITHUB_REPOSITORY_SLUG": "${GITHUB_REPOSITORY_SLUG}",
"GITHUB_REF_SLUG_URL": "${GITHUB_REF_SLUG_URL}",
"GITHUB_HEAD_REF_SLUG_URL": "${GITHUB_HEAD_REF_SLUG_URL}",
"GITHUB_BASE_REF_SLUG_URL": "${GITHUB_BASE_REF_SLUG_URL}",
"GITHUB_EVENT_REF_SLUG_URL": "${GITHUB_EVENT_REF_SLUG_URL}",
"GITHUB_REPOSITORY_SLUG_URL": "${GITHUB_REPOSITORY_SLUG_URL}",
"GITHUB_SHA_SHORT": "${GITHUB_SHA_SHORT}"
}
EOF
}
echo "Print generate_post_data():"
echo "$(generate_post_data)"
echo "Calling webhook at '$VERCEL_DEPLOYMENT_COMPLETED_WEBHOOK'"
echo "Sending HTTP request (curl):"
curl POST \
"$VERCEL_DEPLOYMENT_COMPLETED_WEBHOOK" \
-vs \
--header "Accept: application/json" \
--header "Content-type: application/json" \
--data "$(generate_post_data)" \
2>&1 | sed '/^* /d; /bytes data]$/d; s/> //; s/< //'
# XXX See https://stackoverflow.com/a/54225157/2391795
# -vs - add headers (-v) but remove progress bar (-s)
# 2>&1 - combine stdout and stderr into single stdout
# sed - edit response produced by curl using the commands below
# /^* /d - remove lines starting with '* ' (technical info)
# /bytes data]$/d - remove lines ending with 'bytes data]' (technical info)
# s/> // - remove '> ' prefix
# s/< // - remove '< ' prefix
else
echo "No webhook url defined in 'vercel.$CUSTOMER_REF_TO_DEPLOY.staging.json:.build.env.VERCEL_DEPLOYMENT_COMPLETED_WEBHOOK' (found '$VERCEL_DEPLOYMENT_COMPLETED_WEBHOOK')"
fi
对于 PowerShell,我使用了:
curl.exe -H "Content-Type: application/json" --data "@content.json" http://localhost:8080/appname/path
其中 content.json 是本地包含请求的 JSON 文件的名称,而不仅仅是不使用 Invoke-WebRequest 的别名。curl.exe
curl
或者,如果要直接指定 JSON:
curl.exe -H "Content-Type: application/json" --data '{\"username\":\"xyz\",\"password\":\"xyz\"}' http://localhost:8080/appname/path
- -H 在标头中发送类似 content-type 或身份验证令牌的内容
- -d 在这里添加您的数据
- 最后添加站点链接
注意:不要忘记为身份验证凭据添加身份验证令牌(如果有)
curl -X POST -H 'Content-Type: application/json' -H 'Authorization: Token 2de403987713595a7955a9b4655b9e206d4294b3' -d '{"title":"Post test with curl", "body": "test body"}' http://127.0.0.1:8000/api/v1/feeds/
问题就在这里:
HTTP/1.1 415 Unsupported Media Type
服务器登录无法解释此请求的媒体类型,因此它将其解析为 text/html
任何资源的媒体类型都在 Content-Type 中声明 请求标头的属性
“接受”......标头将失败此请求,因此发送任何 JSON 请求都需要以下内容,即 content-type
-H 'content-type: application/json'
假设数据和 URL 是这样的
{“电子邮件”: “[email protected]”,“密码”: “123456”}
http://localhost:5000/api/login
然后在 Linux 中
curl http://localhost:5000/api/login -H 'content-type: application/json' -d '{"email": "[email protected]", "password": "123456"}'
在 Windows 中(参数两边的单引号将不起作用)
curl http://localhost:5000/api/login -H "content-type: application/json" -d "{\"email\": \"[email protected]\", \"password\": \"123456\"}"
当命令中存在 -d {.....} 时,不需要 -X POST 键。
对于 PUT 请求:
-X PUT
TL;博士:
jo value=30 type="Tip 3" targetModule="Target 3" configurationGroup=null name="Configuration Deneme 3" description=null identity="Configuration Deneme 3" | \
curl --json @- \
-X POST \
http://localhost:8080/xx/xxx/xxxx | \
jq
这将涵盖缺少的必要标头:无需显式定义 和 标头。Content-Type
Accept
使用 --json 的新 curl 方式
2022 年 3 月初,发布了 7.82.0 版的新命令行参数。这允许通过 JSON 发送快捷方式,并且无需定义您缺少的标头和标头,因为这些是自动假设的,从而降低了出错的风险:curl
--json
Content-Type
Accept
curl --json '{"tool": "curl"}' https://example.com/
但是等等......还有更多。与其将 json 参数定义为命令行的字符串,不如使用漂亮的 jo
CLI 工具将 JSON 定义为一系列键值对,并通过 curl 管道传输输出。仅用于定义 JSON,其工作方式如下:curl
jo
> jo -p value=30 type="Tip 3" targetModule="Target 3" configurationGroup=null name="Configuration Deneme 3" description=null identity="Configuration Deneme 3"
version=0 systemId=3 active=true
{
"value": 30,
"type": "Tip 3",
"targetModule": "Target 3",
"configurationGroup": null,
"name": "Configuration Deneme 3",
"description": null,
"identity": "Configuration Deneme 3",
"version": 0,
"systemId": 3,
"active": true
}
现在让我们用你的类似命令来展示这一点,但没有额外的标头,并使用 + 来获得漂亮的输出:curl
jo
jq
jo value=30 type="Tip 3" targetModule="Target 3" configurationGroup=null name="Configuration Deneme 3" description=null identity="Configuration Deneme 3" | \
curl --json @- \
-X POST \
http://localhost:8080/xx/xxx/xxxx | \
jq
使用免费 API 的示例
使用免费的模拟 API 进行演示:
> jo title="Blog Post" body="lorem ipsum" userId=33 | \
curl --json @- \
-X POST \
https://jsonplaceholder.typicode.com/posts | \
jq
由于以下原因,输出具有漂亮的格式:jq
{
"title": "Blog Post",
"body": "lorem ipsum",
"userId": 33,
"id": 101
}
评论
curl
brew
brew upgrade curl
您可以通过参数对 JSON 文件的内容进行 cat 操作。curl
--data-raw
curl 'https://api.com/route' -H 'Content-Type: application/json' --data-raw "$(cat ~/.json/payload-2022-03-03.json | grep -v '^\s*//')"
注意:JSON 文件中的注释通过grep -v '^\s*//'
您还可以使用 或 通过标准输入将数据传递给 。curl
grep
cat
grep -v '^\s*//' ~/.json/payload-2022-03-03.json | curl 'https://api.com/route' -H 'Content-Type: application/json' -d @-
cat ~/.json/payload-2022-03-03.json | grep -v '^\s*//' | curl 'https://api.com/route' -H 'Content-Type: application/json' -d @-
很简单
curl -X POST https://localhost:3000/
-H "Content-Type: application/json"
-d '{"productId": 123456, "quantity": 100}'
--json <data>
将 POST 请求中指定的 JSON 数据发送到 HTTP 服务器。
卷曲 7.82.0+
# Send a basic JSON object
curl --json '{"name":"xyz","breed":"xyz","age":100}' http://127.0.0.1:3000/cats
# letter @, read the data from a file
curl --json @cat.txt http://127.0.0.1:3000/cats
# letter -, read the data from stdin
echo '{"name":"xyz","breed":"xyz","age":100}' | curl --json @- http://127.0.0.1:3000/cats
卷曲 7.82.0-
curl -X POST --header "Content-Type: application/json" --data '{"name":"xyz","breed":"xyz","age":100}' http://127.0.0.1:3000/cats
下面的代码对我有用。
我正在使用示例数据 api
curl -X POST --data @json_out.txt https://sampledataapi.com/API/login
这里解释一下
-X Means the HTTP verb.
--data Means the data you want to send.
若要使用 cURL 对 JSON 数据进行 POST 操作,应使用将数据括在单引号中的标志,并将内容类型指定为使用标志。下面是更正后的 cURL 命令:-d
application/json
-H
curl -i \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-X POST -d '{"value":"30","type":"Tip 3","targetModule":"Target 3","configurationGroup":null,"name":"Configuration Deneme 3","description":null,"identity":"Configuration Deneme 3","version":0,"systemId":3,"active":true}' \
http://localhost:8080/xx/xxx/xxxx
变更说明:
- 添加以指定在请求正文中发送 JSON 数据。
-H "Content-Type: application/json"
- 将 JSON 数据括在单引号 () 中,以确保 cURL 将其视为单个参数。
'
- 包装 JSON 数据以创建有效的 JSON 对象。
{}
这应该可以解决“415 不支持的媒体类型”错误,并且您的 Spring REST 应用程序应该能够正确接受 JSON 数据。
评论
JSON parse error: Unexpected character (''' (code 39)): expected a valid value (JSON String, Number, Array, Object or token 'null', 'true' or 'false')]
评论