为什么卷曲的帖子请求与此普通图书馆邮政请求返回与同一机构的同一地址不同的结果?

发布于 2025-02-03 09:38:02 字数 1939 浏览 2 评论 0原文

我正在使用钢库普通LISP(SBCL),emacs,slime和一个名为 dexador )的库。

在补充中,我可以做:

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,。

我期望这两个结果都是相同的,因为它们指向相同的地址并具有相同的主体。

为什么它们与众不同?我想念什么吗?

I am using Steel Bank Common Lisp (SBCL), Emacs, Slime, and a library called Dexador.

In the REPL, I can do:

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\"
}
"

Removing the escape character, notice the JSON key of the JSON output:

  "json": {
    "pass": "abcd", 
    "user": "user1"
  }

Now, if I try doing the same on curl following this tutorial, this is what I get:


$ 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"
}

Notice the "json": null,.

I was expecting both results to be the same since they are pointing to the same address and have the same body being sent.

Why are they different? Did I miss something?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

成熟稳重的好男人 2025-02-10 09:38:02

设置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 is application> application> 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"
}

Set up netcat:

nc -l -p 3500

Run your curl command against that:

curl -d "user=user1&pass=abcd" -X POST http://localhost:3500/post

Netcat prints:

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

So first, Content-Type is application/x-www-form-urlencoded, because that's what -d means to curl.

Second, the data is sent as user=user1&pass=abcd, not as JSON. That's because curl's default data mode is application/x-www-form-urlencoded, it doesn't just send it as JSON because you hoped it would.
In fact, it doesn't implement JSON at all.

If you want to send JSON, you have to do that explicitly:

jq --null-input '
    .user |= "user1" | 
    .pass |= "abcd"' \
    | curl \
        -H 'Content-Type: text/plain' \
        -d @- \
        -X POST \
        https://httpbin.org/post

Response:

{
  "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"
}
紧拥背影 2025-02-10 09:38:02

如果一个人打开 main github存储库,他将能够在用法 part:

(dex:post "https://example.com/login"
          :content '(("name" . "fukamachi") ("password" . "1ispa1ien")))

表单内容定义为a-list或关联列表。关联列表是通用LISP中非常重要的一件事,如果该函数需要一个参数中的A列表,则不应提供字符串:

(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

If one open the main github repository, he would be able to read the very first example in the Usage part:

(dex:post "https://example.com/login"
          :content '(("name" . "fukamachi") ("password" . "1ispa1ien")))

The form content is defined as a a-list or association list. Association lists are a very important thing in Common Lisp and if the function need a a-list in parameter, you should not provide a string:

(dex:post "https://httpbin.org/post" :content "{\"user\": \"user1\", \"pass\": \"abcd\"}")
                                              ^ this is a string not a a-list

The correct function call would be:

(dex:post "https://httpbin.org/post"
          :content '(("user" . "user1") ("pass" . "abcd")))

And this returns:

(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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文