json - 带 cURL 的 Bash 脚本;不以 JSON 形式发送 POST

标签 json bash rest curl urlencode

我正在创建一个简单的 bash 脚本来运行 cURL POST 命令。 该脚本即使是相同的命令也不会以 json 形式发送 POST 数据。

当我手动输入命令时,它会毫无问题地以 JSON 形式发送 POST 数据。

$ curl --include --header 'Accept:application/json' --header 'Authorization:Basic xxxxxxxxxxxxxxxxx' --data '{"sourceTemplateId":111111111111111}' --header 'Content-Type:application/json' https://api.everbridge.net/rest/notifications/000000000000000
HTTP/1.1 200 OK
Server: nginx/1.8.0
Date: Wed, 18 May 2016 18:13:15 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive

{
  "message" : "OK",
  "id" : 5748251085623370,
  "baseUri" : "https://api.everbridge.net/rest/notifications/000000000000000/",
  "instanceUri" : "https://api.everbridge.net/rest/notifications/000000000000000/5748251085623370"
}

当我为 bash 脚本运行 echo 时,我得到了这个。

$ ./Send_Not.sh
curl --include --header 'Accept:application/json' --header 'Authorization:Basic xxxxxxxxxxxxxxxxx' --data '{"sourceTemplateId":111111111111111}' --header 'Content-Type:application/json' https://api.everbridge.net/rest/notifications/000000000000000

格式完全相同

但是当我运行脚本时,出现此错误。

$ ./Send_Not.sh
HTTP/1.1 415 Unsupported Media Type
Server: nginx/1.8.0
Date: Wed, 18 May 2016 18:28:50 GMT
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive

{
  "status" : 415,
  "message" : "Content type 'application/x-www-form-urlencoded' not supported"

这是我的脚本,非常简单。

#!/bin/bash
ajson=\'Accept:application/json\'
credentials=\'Authorization:Basic\ xxxxxxxxxxxxxxxxx\'
data=\'{\"sourceTemplateId\":111111111111111}\'
CT=\'Content-Type:application/json\'
url="https://api.everbridge.net/rest/notifications/000000000000000"

curl --include --header "$ajson" --header "$credentials" --data "$data" --header "$CT" "$url"

使用 -X POST 和 -v 重新运行命令

$ ./Send_Not.sh
Note: Unnecessary use of -X or --request, POST is already inferred.
* STATE: INIT => CONNECT handle 0x600057830; line 1108 (connection #-5000)
* Added connection 0. The cache now contains 1 members
*   Trying 54.193.84.167...
* STATE: CONNECT => WAITCONNECT handle 0x600057830; line 1161 (connection #0)
* Connected to api.everbridge.net (54.193.84.167) port 443 (#0)
* STATE: WAITCONNECT => SENDPROTOCONNECT handle 0x600057830; line 1260 (connection #0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* STATE: SENDPROTOCONNECT => PROTOCONNECT handle 0x600057830; line 1274 (connection #0)
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-SHA
* ALPN, server did not agree to a protocol
* Server certificate:
*  subject: C=US; ST=California; L=Glendale; O=Everbridge; OU=SaaS Operations; CN=*.everbridge.net
*  start date: Sep 18 00:00:00 2015 GMT
*  expire date: Sep 17 23:59:59 2018 GMT
*  subjectAltName: host "api.everbridge.net" matched cert's "*.everbridge.net"
*  issuer: C=US; O=GeoTrust Inc.; CN=GeoTrust SSL CA - G3
*  SSL certificate verify ok.
* STATE: PROTOCONNECT => DO handle 0x600057830; line 1295 (connection #0)
> POST /rest/notifications/000000000000000 HTTP/1.1
> Host: api.everbridge.net
> User-Agent: curl/7.48.0
> Accept: */*
> 'Accept:application/json'
> 'Authorization:Basic xxxxxxxxxxxxxxxxx'
> 'Content-Type:application/json'
> Content-Length: 39
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 39 out of 39 bytes
* STATE: DO => DO_DONE handle 0x600057830; line 1357 (connection #0)
* STATE: DO_DONE => WAITPERFORM handle 0x600057830; line 1484 (connection #0)
* STATE: WAITPERFORM => PERFORM handle 0x600057830; line 1494 (connection #0)
* HTTP 1.1 or later with persistent connection, pipelining supported
< HTTP/1.1 415 Unsupported Media Type
HTTP/1.1 415 Unsupported Media Type
* Server nginx/1.8.0 is not blacklisted
< Server: nginx/1.8.0
Server: nginx/1.8.0
< Date: Wed, 18 May 2016 21:08:12 GMT
Date: Wed, 18 May 2016 21:08:12 GMT
< Content-Type: application/json;charset=UTF-8
Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
Transfer-Encoding: chunked
< Connection: keep-alive
Connection: keep-alive

<
{
  "status" : 415,
  "message" : "Content type 'application/x-www-form-urlencoded' not supported"
* STATE: PERFORM => DONE handle 0x600057830; line 1652 (connection #0)
* Curl_done
* Connection #0 to host api.everbridge.net left intact
}

回显 Mircea 建议的新脚本

$ ./Send_Not.sh
curl -vvv --include --header 'Accept:application/json' --header 'Authorization:Basic xxxxxxxxxxxxxxxxx' -X POST --data '{"sourceTemplateId":111111111111111}' --header Content-Type:application/json https://api.everbridge.net/rest/notifications/000000000000000

执行新脚本时回复

$ ./Send_Not.sh
Note: Unnecessary use of -X or --request, POST is already inferred.
* STATE: INIT => CONNECT handle 0x600057830; line 1108 (connection #-5000)
* Added connection 0. The cache now contains 1 members
*   Trying 54.193.84.167...
* STATE: CONNECT => WAITCONNECT handle 0x600057830; line 1161 (connection #0)
* Connected to api.everbridge.net (54.193.84.167) port 443 (#0)
* STATE: WAITCONNECT => SENDPROTOCONNECT handle 0x600057830; line 1260 (connection #0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* STATE: SENDPROTOCONNECT => PROTOCONNECT handle 0x600057830; line 1274 (connection #0)
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-SHA
* ALPN, server did not agree to a protocol
* Server certificate:
*  subject: C=US; ST=California; L=Glendale; O=Everbridge; OU=SaaS Operations; CN=*.everbridge.net
*  start date: Sep 18 00:00:00 2015 GMT
*  expire date: Sep 17 23:59:59 2018 GMT
*  subjectAltName: host "api.everbridge.net" matched cert's "*.everbridge.net"
*  issuer: C=US; O=GeoTrust Inc.; CN=GeoTrust SSL CA - G3
*  SSL certificate verify ok.
* STATE: PROTOCONNECT => DO handle 0x600057830; line 1295 (connection #0)
> POST /rest/notifications/000000000000000 HTTP/1.1
> Host: api.everbridge.net
> User-Agent: curl/7.48.0
> Accept: */*
> 'Accept:application/json'
> 'Authorization:Basic xxxxxxxxxxxxxxxxx'
> Content-Type:application/json
> Content-Length: 39
>
* upload completely sent off: 39 out of 39 bytes
* STATE: DO => DO_DONE handle 0x600057830; line 1357 (connection #0)
* STATE: DO_DONE => WAITPERFORM handle 0x600057830; line 1484 (connection #0)
* STATE: WAITPERFORM => PERFORM handle 0x600057830; line 1494 (connection #0)
* HTTP 1.1 or later with persistent connection, pipelining supported
< HTTP/1.1 400 Bad Request
HTTP/1.1 400 Bad Request
* Server nginx/1.8.0 is not blacklisted
< Server: nginx/1.8.0
Server: nginx/1.8.0
< Date: Wed, 18 May 2016 21:41:01 GMT
Date: Wed, 18 May 2016 21:41:01 GMT
< Content-Type: application/json;charset=UTF-8
Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
Transfer-Encoding: chunked
< Connection: keep-alive
Connection: keep-alive

<
{
  "status" : 400,
  "message" : "Error Unexpected character (''' (code 39)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')\n at [Source: org.apache.tools.ant.filters.StringInputStream@5d5906fc; line: 1, column: 2] parsing input:\n'{\"sourceTemplateId\":111111111111111}'"
* STATE: PERFORM => DONE handle 0x600057830; line 1652 (connection #0)
* Curl_done
* Connection #0 to host api.everbridge.net left intact
}

我还转义了 Conten-Type 的双引号,并且得到了原始错误

#!/bin/bash
ajson="Accept:application/json"
credentials="Authorization:Basic xxxx_replace_xxxx"
data='{"sourceTemplateId":111111111111111}'
CT=\"Content-Type:application/json\"
url="https://api.everbridge.net/rest/notifications/000000000000000"

curl -vvv --include --header "$ajson" --header "$credentials" --data "$data" --header "$CT" "$url"

执行时出现原始错误

$ ./Send_Not.sh
Note: Unnecessary use of -X or --request, POST is already inferred.
* STATE: INIT => CONNECT handle 0x600057830; line 1108 (connection #-5000)
* Added connection 0. The cache now contains 1 members
*   Trying 54.193.84.167...
* STATE: CONNECT => WAITCONNECT handle 0x600057830; line 1161 (connection #0)
* Connected to api.everbridge.net (54.193.84.167) port 443 (#0)
* STATE: WAITCONNECT => SENDPROTOCONNECT handle 0x600057830; line 1260 (connection #0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* STATE: SENDPROTOCONNECT => PROTOCONNECT handle 0x600057830; line 1274 (connection #0)
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-SHA
* ALPN, server did not agree to a protocol
* Server certificate:
*  subject: C=US; ST=California; L=Glendale; O=Everbridge; OU=SaaS Operations; CN=*.everbridge.net
*  start date: Sep 18 00:00:00 2015 GMT
*  expire date: Sep 17 23:59:59 2018 GMT
*  subjectAltName: host "api.everbridge.net" matched cert's "*.everbridge.net"
*  issuer: C=US; O=GeoTrust Inc.; CN=GeoTrust SSL CA - G3
*  SSL certificate verify ok.
* STATE: PROTOCONNECT => DO handle 0x600057830; line 1295 (connection #0)
> POST /rest/notifications/000000000000000 HTTP/1.1
> Host: api.everbridge.net
> User-Agent: curl/7.48.0
> Accept: */*
> 'Accept:application/json'
> 'Authorization:Basic xxxxxxxxxxxxxxxxxx'
> "Content-Type:application/json"
> Content-Length: 39
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 39 out of 39 bytes
* STATE: DO => DO_DONE handle 0x600057830; line 1357 (connection #0)
* STATE: DO_DONE => WAITPERFORM handle 0x600057830; line 1484 (connection #0)
* STATE: WAITPERFORM => PERFORM handle 0x600057830; line 1494 (connection #0)
* HTTP 1.1 or later with persistent connection, pipelining supported
< HTTP/1.1 415 Unsupported Media Type
HTTP/1.1 415 Unsupported Media Type
* Server nginx/1.8.0 is not blacklisted
< Server: nginx/1.8.0
Server: nginx/1.8.0
< Date: Wed, 18 May 2016 21:48:54 GMT
Date: Wed, 18 May 2016 21:48:54 GMT
< Content-Type: application/json;charset=UTF-8
Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
Transfer-Encoding: chunked
< Connection: keep-alive
Connection: keep-alive

<
{
  "status" : 415,
  "message" : "Content type 'application/x-www-form-urlencoded' not supported"
* STATE: PERFORM => DONE handle 0x600057830; line 1652 (connection #0)
* Curl_done
* Connection #0 to host api.everbridge.net left intact
}

最佳答案

正如评论中所述,这是一个关于你如何逃避事物的问题。
以下是有效脚本的一种形式:

#!/bin/bash
ajson="Accept:application/json"
credentials="Authorization:Basic xxxx_replace_xxxx"
data='{"sourceTemplateId":111111111111111}'
CT="Content-Type:application/json"
url="https://api.everbridge.net/rest/notifications/000000000000000"

curl -vvv --include --header "$ajson" --header "$credentials" --data "$data" --header "$CT" "$url"

关于json - 带 cURL 的 Bash 脚本;不以 JSON 形式发送 POST,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37307594/

相关文章:

linux - 将变量传递给 bash 数组中的 `expect`

bash - sed 仅在时间范围内提取数据

python - obj_create 无法在 tastypie 中工作

python - 如何使用请求发送具有 unicode 名称的文件

javascript - 无法将数据从 Angular 应用程序发布到 Play!框架

php - XML 中的 CDATA 中的 JSON - 适用于本地主机 (WAMP),但不适用于主机 (LINUX)

json - 检查 Postgres JSON 数组是否包含字符串

java - 如何使用 Jersey 2.x 发送 JSON 请求

linux - linux脚本中这个链接的含义是什么

java - 泽西 REST 标志 xml