我正在使用 Steel Bank Common Lisp (SBCL)、Emacs、Slime 和一個名為Dexador的庫。
在 REPL 中,我可以這樣做:
CL-USER> (dex:post "https://httpbin.org/post"
:content "{\"user\": \"user1\", \"pass\":\"abcd\"}")
"{
\"args\": {},
\"data\": \"{\\\"user\\\": \\\"user1\\\", \\\"pass\\\": \\\"abcd\\\"}\",
\"files\": {},
\"form\": {},
\"headers\": {
\"Accept\": \"*/*\",
\"Content-Length\": \"33\",
\"Content-Type\": \"text/plain\",
\"Host\": \"httpbin.org\",
\"User-Agent\": \"Dexador/0.9.15 (SBCL 2.1.9.nixos); Linux; 5.10.94\",
\"X-Amzn-Trace-Id\": \"Root=1-62956dc4-1b95d37752a67b8420180f71\"
},
\"json\": {
\"pass\": \"abcd\",
\"user\": \"user1\"
},
\"origin\": \"189.2.84.243\",
\"url\": \"https://httpbin.org/post\"
}
"
洗掉轉義字符,注意 JSON 輸出的 JSON 鍵:
"json": {
"pass": "abcd",
"user": "user1"
}
現在,如果我按照本教程嘗試在 curl 上做同樣的事情,這就是我得到的:
$ curl -d "user=user1&pass=abcd" -X POST https://httpbin.org/post
{
"args": {},
"data": "",
"files": {},
"form": {
"pass": "abcd",
"user": "user1"
},
"headers": {
"Accept": "*/*",
"Content-Length": "20",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"User-Agent": "curl/7.79.1",
"X-Amzn-Trace-Id": "Root=1-62956e50-4e880d101ac23b781fe0f9d5"
},
"json": null,
"origin": "189.2.84.243",
"url": "https://httpbin.org/post"
}
注意 "json": null,.
我期望這兩個結果是相同的,因為它們指向相同的地址并且發送相同的正文。
為什么它們不同?我錯過了什么?
uj5u.com熱心網友回復:
設定netcat:
nc -l -p 3500
對此運行您的curl命令:
curl -d "user=user1&pass=abcd" -X POST http://localhost:3500/post
Netcat 列印:
POST /post HTTP/1.1
Host: localhost:3500
User-Agent: curl/7.68.0
Accept: */*
Content-Length: 20
Content-Type: application/x-www-form-urlencoded
user=user1&pass=abcd
所以首先Content-Type是application/x-www-form-urlencoded,因為這就是 的-d意思curl。
其次,資料以user=user1&pass=abcd.,而不是 JSON 格式發送。那是因為curl的默認資料模式是application/x-www-form-urlencoded,它不只是將它作為 JSON 發送,因為你希望它會。
事實上,它根本沒有實作 JSON。
如果你想發送 JSON,你必須明確地這樣做:
jq --null-input '
.user |= "user1" |
.pass |= "abcd"' \
| curl \
-H 'Content-Type: text/plain' \
-d @- \
-X POST \
https://httpbin.org/post
回復:
{
"args": {},
"data": "{ \"user\": \"user1\", \"pass\": \"abcd\"}",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Content-Length": "36",
"Content-Type": "text/plain",
"Host": "httpbin.org",
"User-Agent": "curl/7.68.0",
"X-Amzn-Trace-Id": "Root=1-6295a78d-0d828c3c6d3891174fd22d01"
},
"json": {
"pass": "abcd",
"user": "user1"
},
"origin": "71.122.242.250",
"url": "https://httpbin.org/post"
}
uj5u.com熱心網友回復:
如果打開主 github 存盤庫,他將能夠閱讀該Usage部分中的第一個示例:
(dex:post "https://example.com/login"
:content '(("name" . "fukamachi") ("password" . "1ispa1ien")))
表單內容定義為 a-list 或關聯串列。關聯串列在 Common Lisp 中非常重要,如果函式需要在引數中使用 a-list,則不應提供字串:
(dex:post "https://httpbin.org/post" :content "{\"user\": \"user1\", \"pass\": \"abcd\"}")
^ this is a string not a a-list
正確的函式呼叫是:
(dex:post "https://httpbin.org/post"
:content '(("user" . "user1") ("pass" . "abcd")))
這會回傳:
(dex:post "https://httpbin.org/post"
:content '(("user" . "user1") ("pass" . "abcd")))
#<(SIMPLE-ARRAY CHARACTER (464)) {
"args": {},
"data": "",
"files": {},
"form": { ;;
"pass": "abcd", ;; The data is here
"user": "user1" ;;
}, ;;
"headers": {
"Content-Length": "20",
"Content-Type": "application/x-www-form-urlen... {10076E5CCF}>
200
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/484718.html
