【问题标题】:cURL command works in git bash but not in cmd and powershellcURL 命令在 git bash 中有效,但在 cmd 和 powershell 中无效
【发布时间】:2020-03-24 20:39:54
【问题描述】:

以下命令在 git bash 中有效,但在 cmd 和 powershell 中无效

curl -X POST http://localhost:5678/api/findgen -H 'Content-Type: application/json' -d '{"a": "Val 1","b": "Val 2","c": "Val 3","d": "Val 4"}' -o "file.json"

我在 cmd 中遇到错误,例如 -

curl: (6) 无法解析主机:应用程序

curl: (6) 无法解析主机:Val 1,b

curl: (6) 无法解析主机:Val 2,c

curl: (6) 无法解析主机:Val 3,d

curl: (3) [globbing] 第 6 列中不匹配的右大括号/方括号

可能是什么问题?

【问题讨论】:

    标签: powershell api curl cmd git-bash


    【解决方案1】:

    只需阅读错误信息:

    Invoke-WebRequest 无法绑定参数“标头”。无法转换“内容类型: 要键入的“System.String”类型的 application/json" 值 “System.Collections.IDictionary”。

    在 PowerShell 中,curlInvoke-WebRequest cmdlet 的别名。正如错误指出的那样,Header 参数必须是 IDictionary,而不是字符串。这是它在 PowerShell 中的样子:

    @{"Content-Type"= "application/json"}

    有些参数也不同。这就是我编写请求的方式:

    Invoke-WebRequest `
        -Uri "http://localhost:5678/api/findgen" `
        -Headers @{"Content-Type"= "application/json"} `
        -Body '{"a": "Val 1","b": "Val 2","c": "Val 3","d": "Val 4"}' `
        -OutFile "file.json" `
        -Method Post
    

    【讨论】:

    • 此答案所指的错误消息在问题中不存在。该问题显示来自真实卷曲的错误消息。这非常令人困惑!
    【解决方案2】:

    由于Windows curl.exe native program 解释单引号和双引号的方式,我只能在 Windows 10(内部版本 17063 或更高版本)上看到带有 C:\Windows\System32\curl.exe 的“Could not resolve host”。

    如果你反转/转义这些引号,它确实有效(在 CMD 上)

    C:\Windows\System32\curl -X POST http://localhost:5678/api/findgen \
      -H "Content-Type: application/json" \
        ^^^
         double-quotes
      -d "{\"a\": \"Val 1\",\"b\": \"Val 2\",\"c\": \"Val 3\",\"d\": \"Val 4\"}" -o "file.json"
         ^^^
         double quotes outside, escaped double-quotes inside: valid JSON
    

    这类似于“How do I POST JSON with Curl?

    在 Powershell 上,我必须转义双引号(反引号,如评论),并转义 {}: {{}}

    PS D:\> C:\Windows\System32\curl -X POST https://reqbin.com/echo/post/json `
       -H "Content-Type: application/json" `
       -d "{{`"login`":`"my_login`",`"password`":`"my_password`"}}"
    

    或者:

    PS D:\> C:\Windows\System32\curl.exe -X POST https://reqbin.com/echo/post/json `
    >>    -H "Content-Type: application/json" `
    >>    -d '{{""login"":""my_login"",""password"":""my_password""}}'
    {"success":"true"}
    

    来自史蒂文的帖子:

    PS D:\> C:\Windows\System32\curl.exe -X POST -H "Content-Type: application/json" `
        -d '{""north"": ""each south""}' https://reqbin.com/echo/post/json
    {"success":"true"}
    

    单独使用 curl.exe 意味着使用 MingW Git for Windows curl.exe

    PS D:\> curl.exe -X POST -H "Content-Type: application/json" `
    >>     -d '{""north"": ""each south""}' https://reqbin.com/echo/post/json
    curl: (6) Could not resolve host: each
    curl: (3) unmatched close brace/bracket in URL position 6:
    south} https://reqbin.com/echo/post/json
    

    因此,您需要转义大括号,并删除所有空格:

    PS D:\> curl.exe -X POST -H "Content-Type: application/json" `
    >>     -d '{{"north":"each south"}}' https://reqbin.com/echo/post/json
    {"success":"true"}
    

    或者,使用空格,单引号:

    PS D:\> curl.exe -X POST -H "Content-Type: application/json" `
    >>     -d '{\"north\": \"each south\"}' https://reqbin.com/echo/post/json
    {"success":"true"}
    

    在 CMD 上如果您想保持这些引号不变,请使用与 Git For Windows 打包的 mingw curl.exe,至少在 CMD 上。

    C:\path\to\git\mingw64\bin\curl.exe -X POST http://localhost:5678/api/findgen \
      -H 'Content-Type: application/json' \
      -d '{"a": "Val 1","b": "Val 2","c": "Val 3","d": "Val 4"}' -o "file.json"
         ^^^
         You can keep the quotes as-is
    

    作为commented,在Powershell 会话中,curl 本身就是Invoke-WebRequest 的别名。

    我测试过:

    PS D:\> Get-Alias -Name curl
    
    CommandType     Name                                               Version    Source
    -----------     ----                                               -------    ------
    Alias           curl -> Invoke-WebRequest
    
    
    PS D:\> curl -uri https://reqbin.com/echo/post/json `
    >>     -Method 'POST' -ContentType "application/json" `
    >>     -Body "{""login"":""my_login"",""password"":""my_password""}"
    
    
    StatusCode        : 200
    StatusDescription : OK
    Content           : {"success":"true"}
    
    RawContent        : HTTP/1.1 200 OK
                        Connection: keep-alive
                        CF-Cache-Status: DYNAMIC
                        cf-request-id: 0917a97460000053c82aa69000000001
                        Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/bea...
    Forms             : {}
    Headers           : {[Connection, keep-alive], [CF-Cache-Status, DYNAMIC], [cf-request-id, 0917a97460000053c82aa69000000001], [Expect-CT, max-age=604800,
                        report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"]...}
    Images            : {}
    InputFields       : {}
    Links             : {}
    ParsedHtml        : System.__ComObject
    RawContentLength  : 19
    

    【讨论】:

    • @StevenPenny 我已经编辑了第一个示例(并在 Powershell 会话中对其进行了测试)
    • @StevenPenny 我已经编辑了我的答案,以使您删除的答案示例正常工作。 (在 PowerShell 会话中测试)
    • @StevenPenny 注意带有这种语法的单个 {...} 大括号(不需要{{...}}
    • @StevenPenny 我刚刚在 PowerShell 会话中复制/粘贴了最后一次编辑,从 C:\Windows\System32\curl.exe 开始(确保使用“正确的”curl):我得到了{"success":"true"}$PSVersionTable.PSVersion 5 1 19041 610 在 Windows 10 20H2 上
    • @StevenPenny OK:已添加空间。仍然成功(但使用 -X POST 和 -H 作为 JSON 标头)。并使用{...},而不是{{...}}
    【解决方案3】:

    所以这里是改编的语法作为一个衬里:

    curl.exe "-X" "POST" "https://reqbin.com/echo/post/json" `
    "-H" "Content-Type: application/json" `
    "-d" '{\"a\": \"Val 1\",\"b\": \"Val 2\",\"c\": \"Val 3\",\"d\": \"Val 4\"}' `
    "-o" "file.json"
    

    还有一种对 JSON 更友好的方式:

    curl.exe "-X" "POST" "https://reqbin.com/echo/post/json" `
    "-H" "Content-Type: application/json" `
    "-d" (@{a='Val 1';b='val 2';c='Val 3';d='Val 4'} | ConvertTo-Json -Compress) `
    "-o" "file.json"
    

    【讨论】:

    • 我与--trace-ascii 确认这会产生正确的请求。如果没有更好的答案,那么这将获得赏金 - 谢谢
    • @StevenPenny 你认为我们应该添加纯 CMD 吗? (curl.exe "-X" "POST" "https://reqbin.com/echo/post/json" "-H" "Content-Type: application/json" "-d" "{""a"": ""Val 1"",""b"": ""Val 2"",""c"": ""Val 3"",""d"": ""Val 4""}" "-o" "file.json")
    • 个人 CMD 是旧的,所以我会忽略它
    猜你喜欢
    • 2019-01-19
    • 2022-12-21
    • 2021-11-01
    • 1970-01-01
    • 2021-02-26
    • 2021-11-26
    • 2017-03-26
    • 2014-08-13
    • 1970-01-01
    相关资源
    最近更新 更多