简体   繁体   中英

cURL command works in git bash but not in cmd and powershell

The folowing command works in git bash but not in cmd and 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"

I get error in cmd such as -

curl: (6) Could not resolve host: application

curl: (6) Could not resolve host: Val 1,b

curl: (6) Could not resolve host: Val 2,c

curl: (6) Could not resolve host: Val 3,d

curl: (3) [globbing] unmatched close brace/bracket in column 6

What can be the issue?

Just read the error message:

Invoke-WebRequest Cannot bind parameter 'Headers'. Cannot convert the "Content-Type: application/json" value of type "System.String" to type "System.Collections.IDictionary".

In PowerShell, curl is an alias for the Invoke-WebRequest cmdlet. As the error points it out, the Header parameter must be a IDictionary, not a string. This is how it looks like in PowerShell:

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

Some parameters are also different. This is how I would script the request:

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

I see those " Could not resolve host " only with C:\\Windows\\System32\\curl.exe on Windows 10 (build 17063 or later), because of the way the Windows curl.exe native program interprets single and double quotes.

If you inverse/escape those quotes, it does work (on 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

This is similar to " How do I POST JSON with Curl? "

On Powershell, I had to escape double quotes (backtick, as commented), and escape {} : {{}}

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

Alternatively:

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

From Steven's post:

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

Using curl.exe alone means using the 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

You therefore need to escape curly brackets, and remove any space:

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

Or, using spaces, with single quotes:

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

On CMD If you want to keep those quotes unchanged, used the mingw curl.exe packaged with Git For Windows , at least on 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

As commented , in a Powershell session, curl itself is an alias for Invoke-WebRequest .

I tested it with:

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

So here is the adapted syntax as a one liner :

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"

And a way a little more friendly for 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"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM