尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Windows下curl命令实战:从基础命令到SSL报错排查

发布时间:2026/9/26 22:46:47

资讯中心
01
ARTICLE

Windows下curl命令实战:从基础命令到SSL报错排查

Windows下curl命令实战:从基础命令到SSL报错排查
你要是刚从 Linux 或 macOS 切到 Windows最不习惯的一件事估计就是“命令没了”。好在从 Windows 10 1803 开始微软把 curl.exe 直接塞进了系统目录不再是“需要额外装一个东西”的第三方小工具。你现在打开 CMD 或 Windows Terminal敲一句curl --version能直接看到 curl 版本号这事在七八年前根本不敢想。不过真到了上手那一步绝大多数 Windows 用户都会踩同一个坑命令行里明明敲的是curl系统却给你弹一个“Invoke-WebRequest”的报错或者一整屏看不懂的红色信息。这篇文章我从 Windows 自带 curl 的实际情况说起把常用命令、引号转义、SSL 报错、脚本化调用这些点挨个讲透顺便把我踩过的坑和排查思路也写出来。适合刚开始在 Windows 上写脚本、调试接口、下载文件的人看完你就能直接把 curl 当日常工具用起来。1. Windows 端 curl 的前世今生与版本陷阱1.1 内置 curl 的来龙去脉很多老教程还在教你去下载 cURL 的 Windows 压缩包、配置 PATH其实现在已经完全没必要了。微软在 2018 年发布的 Windows 10 1803 版本里就把 curl.exe 放进了C:\Windows\System32跟 ping、ipconfig 这些系统命令放在一起。这意味着只要你的系统不是老掉牙的 Windows 7 或更早版本curl 天然可用。这个内置版本并不是微软自己闭门造的车而是 curl 官方项目与微软合作将官方构建产物直接集成进系统。Windows 10/11 上的 curl 版本号会跟随系统更新走但一般不会第一时间同步到上游最新版。比如我这边系统里的 curl 可能是 7.83 或 8.x而上游已经出到 8.10 了。日常使用完全没问题除非你冲着某些新特性去才需要手动装新版本。还需要注意一点Windows 内置的 curl 默认走的是 Windows 的原生 TLS 后端schannel而不是 Linux 上常见的 OpenSSL。这带来的直接后果是同样的 HTTPS 请求在 Windows 上遇到证书问题时报错形式和 Linux 上不太一样。很多人拿网上 Linux 的排查经验套到 Windows 上结果对不上号越排查越懵。1.2 为什么你在 PowerShell 里敲 curl 会报错这是 Windows 上最经典的新手陷阱。PowerShell 为了兼容旧习惯把curl这个名字默认绑定成了Invoke-WebRequest的别名。也就是说你在 PowerShell 里输入curl http://www.example.com系统真正执行的是Invoke-WebRequest返回的不是你要的网页源码而是一个包含一大堆属性的对象。如果你想在 PowerShell 里坚持用真正的 curl有两个办法# 直接调用 curl.exe 可执行文件 curl.exe http://www.example.com # 或者先删除别名一了百了 Remove-Item Alias:curl -Force我平时更推荐第一种不删别名全部写curl.exe。因为删别名只对当前会话有效新开一个窗口又得重来。把curl.exe写进脚本里还有个好处无论你的脚本以后是在 CMD、PowerShell 还是 Windows Terminal 里跑行为都是一致的不会因为执行环境不同而出现莫名奇妙的差异。如果你用 CMD命令提示符不存在这个别名问题直接curl就能用。但既然现在 Windows Terminal 已经很普及我还是建议你统一用curl.exe的写法省心。1.3 如何查看版本与 TLS 后端判断当前 curl 用的是哪种 TLS 后端可以敲这一行curl --version输出大概长这样curl 8.1.2 (x86_64-pc-win32) libcurl/8.1.2 Schannel Release-Date: 2023-05-30 Protocols: dict file ftp ftps http https mqtt pop3 ... Features: alt-svc AsynchDNS HSTS IPv6 Largefile ...看到Schannel就说明走的是 Windows 原生 TLS 后端。有些自行下载的构建版本会显示OpenSSL。两种后端都能正常发 HTTPS 请求但证书验证逻辑、报错文本有差异排查时先看清这个信息能少走一半弯路。如果系统自带版本确实太老或者你需要多协议支持、想要最新特性可以直接去 curl 官网下载 Windows 版或者用 winget 快速安装winget install curl装完以后注意一下 PATH 顺序。用where curl可以查看当前会优先调用哪个 curl 程序where curl如果输出里 System32 排在前面说明你还在用系统内置版如果某个手动安装目录排在前面说明自定义版本生效了。这个细节很容易被忽略经常有人以为自己装好了新版本结果调用的还是旧版。2. 基础命令实操——从 GET 到 POST 一次讲透2.1 GET 请求与常用输出参数最简单的用法就是直接跟一个 URL。我拿http://www.example.com举例curl.exe http://www.example.com这条命令会把网页的 HTML 源码直接打印到终端。如果 URL 里有特殊字符建议用双引号包起来。在 CMD 里双引号是万能保险在 PowerShell 里双引号里的$有变量展开的效果需要小心一点。实际工作里直接裸打 GET 的情况不算多更多时候你会需要这些参数# 显示响应头 响应体 curl.exe -i http://www.example.com # 只显示响应头 curl.exe -I http://www.example.com # 跟随 301/302 重定向 curl.exe -L https://example.com # 保存响应体到文件 curl.exe -o output.html http://www.example.com # 静默模式不显示进度条出错时才显示 curl.exe -s http://www.example.com这里我想单独聊一下-L。很多人在调用接口时遇到“返回 302 但拿不到最终内容”的问题就是因为忘了加-L。不加-Lcurl 只负责拿到 302 响应后续跳转全凭你自己处理加了-Lcurl 会自动跟踪重定向。这个参数在访问带跳转的下载链接时几乎必加但代价是如果服务器配置了循环重定向curl 会在默认最多 50 次跳转后报错。2.2 POST、JSON 与 Windows 下的引号地狱发一个 POST 请求常见做法是用-X POST配-d参数curl.exe -X POST https://api.example.com/login -d nameadminpassword123456如果接口要收 JSON就需要指定 Content-Typecurl.exe -X POST https://api.example.com/api/data -H Content-Type: application/json -d {\name\:\admin\}写到这一步Windows 用户的价值就体现出来了引号转义真能把人逼疯。在 CMD命令提示符里双引号内的双引号要用\转义上面这种写法是可行的。但一旦字段变多、JSON 嵌套变深肉眼维护这套转义字符串会非常痛苦。我一般不用这个方法。在 PowerShell 里有另一个坑PowerShell 会把双引号里的$当作变量前缀处理如果你 POST 的 JSON 里有$符号比如某个金额字段直接写双引号会出现变量替换把你原本的 JSON 内容改得面目全非。我的解决方案是写临时文件。# 把 JSON 写入 body.json curl.exe -X POST https://api.example.com/api/data -H Content-Type: application/json -d body.json-d body.json表示从文件读取请求体。这个方法有三个好处第一不用处理引号转义第二JSON 可以写得更长、更结构化方便后期维护第三请求体内容可复用。你在 Windows 上调试接口时强烈建议把这个习惯养成。还有个容易踩的坑-X POST不是必须的。当你用了-d参数时curl 会自动把请求方法改为 POST。你只需要写curl.exe -d nameadmin http://www.example.com只有当你想用PUT、DELETE这类方法时才需要显式加-X。很多人用-X POST其实是多此一举反而在某些服务器上引发奇怪的行为。2.3 上传、下载与 Cookie 的使用接口调试里文件上传和 Cookie 维持会话也是高频场景。文件上传用-F参数curl.exe -F fileC:\Users\me\test.jpg https://upload.example.com/这会把test.jpg以 multipart/form-data 格式上传。如果还要附加普通字段再多加一个-Fcurl.exe -F fileC:\Users\me\test.jpg -F description测试图片 https://upload.example.com/下载文件则不外乎-o指定文件名和-O用 URL 末尾文件名curl.exe -L -o myfile.zip https://example.com/download/file.zip如果要带着登录状态访问接口可能需要先登录拿到 Cookie再带着 Cookie 请求# 登录并把 Cookie 保存到文件 curl.exe -c cookie.txt -X POST https://api.example.com/login -d nameadminpassword123456 # 后续请求携带 Cookie curl.exe -b cookie.txt https://api.example.com/profile-c是写入 Cookie 文件-b是读取 Cookie 文件。这个做法在处理需要登录态的接口、内网系统、服务器管理后台时非常好使。别小看它你在 Windows 上调试一个带鉴权的接口如果没有 Cookie 处理能力你可能需要自己从响应头里手工复制 Cookie 拼到请求里那样既不安全也容易错。3. 调试三板斧-v、证书与常见 SSL 报错3.1 -v 参数到底打印了什么接口报错时绝大多数人第一反应是把报错信息复制下来发给同事但 curl 默认只打印一行错误信息量太少。这时候你需要-v参数。-v是 verbose 的缩写会把整个 HTTP 会话的全过程打出来。curl.exe -v https://api.example.com/api/data输出会包括正在解析的主机 IP尝试连接的端口TLS 握手过程包括使用的 TLS 版本和加密套件发出的请求头收到的响应头以我的经验-v输出里最值得关注的几个位置第一是Connected to xxx.xxx.xxx.xxx确认你到底连到了哪个服务器 IP。如果域名解析结果不对问题出在 DNS 上而不是 curl 本身。第二是SSL connection using TLSv1.3确认 TLS 协议版本。有些老服务器只支持 TLS 1.0而新 curl 默认可能不接受老协议这时候就要考虑强制指定--tlsv1.2或者更低版本。第三是请求头里自动带上的User-Agent。有些接口会针对 UA 做拦截当你发现返回结果异常时先看看是不是 UA 被服务器拒绝了。-v还有一个加强版--trace和--trace-asciicurl.exe --trace-ascii trace.log https://api.example.com/api/data它会以十六进制加 ASCII 的方式记录全部网络通信内容比-v更底层、更详细。遇到-v看不出来的诡异问题我会开这个看完整字节流。3.2 SSL 证书问题为什么你会遇到 curl: (60)在 Windows 上用 curl 访问 HTTPS 接口最常见的证书报错是curl: (60) SSL certificate problem: unable to get local issuer certificate这个报错的含义是curl 无法验证服务器证书的签发链。在 Linux 上系统通常自带一套 CA 证书库在 Windows 上curl 走 schannel 时会调用 Windows 的证书存储按理说情况会好一些。但如果你手动的 curl 构建版走的是 OpenSSL 后端它需要自己找 CA 证书文件找不到就会报这个错。遇到这个问题的排查顺序是第一步先检查系统时间对不对。证书有效期校验依赖系统的当前时间如果系统时间错了证书必然被判过期或未生效。这个原因占到了我碰到过的证书报错里相当高的比例别一上来就觉得是服务器问题。第二步确认服务器证书链路是否完整。很多服务器只配置了站点证书没有把中间证书链补全导致客户端无法完成验证。这种情况可以用在线检测工具查也可以让运维把 fullchain 证书配置上。第三步如果接口是内部系统、测试环境证书本身可能就不被信任那你可以加-k参数跳过验证curl.exe -k https://internal.example.com/api但我要强调-k只是调试手段不是解决方案。生产环境里开-k等于把 HTTPS 的防护拆了数据照样会被中间人截取只不过没了证书告警。正规做法是在 Windows 里导入自签名的根证书到“受信任的根证书颁发机构”一劳永逸。3.3 那些让人头疼的 SSL EOF 错误Windows 上还有一种高频报错长这样curl: (35) error:0A000126:SSL routines::unexpected eof while reading这个报错的字面意思是TLS 连接过程中对端突然断开了而且在断开前没有发送正常的 TLS 关闭通知。听起来很绕但实际原因往往没这么复杂。我遇到过的典型情况有几种一种是服务器配置了 TLS 握手超时。如果客户端在握手阶段花费的时间太长服务器等不及就主动断开了。这种时候可以先确认是不是网络跨运营商延迟高或者代理中转导致的。另一种是服务器不接受客户端的 ALPN 协议协商。服务器期望的是 HTTP/2h2但客户端协商失败服务器直接关闭连接。你可以在命令里试试强制指定协议curl.exe --http1.1 https://api.example.com/api或者反过来强制 HTTP/2curl.exe --http2 https://api.example.com/api在 Windows 上还有一个特例如果你用的是走 schannel 的版本偶尔会看到curl: (56) schannel: server closed abruptly (missing close_notify)这其实是同一个问题的不同表现——服务器在 TLS 层没有发送 close_notify 就直接关了 TCP 连接。有些 CDN、负载均衡器为了性能省掉了这个通知导致本地认为连接异常。curl: (56)这类错误在 Windows 上的出现概率不低但只要数据本身已经完整返回实际影响不大。如果影响到了正常请求可以考虑更换 TLS 后端版本或者调整网络环境重试。4. 真实场景排错403、35、56 等报错全复盘4.1 典型报错与排查思路我整理了一份日常排错速查表遇到问题可以直接对照着看。报错信息常见含义优先排查方向curl: (22) The requested URL returned error: 403服务器拒绝访问检查 UA、Referer、Cookie、Tokencurl: (35) SSL connect errorTLS 握手失败检查 TLS 版本、服务器协议支持、网络状况curl: (35) error:0A000126:SSL routines::unexpected eof while reading服务器异常断开尝试--http1.1、检查服务器超时配置curl: (56) schannel: server closed abruptlyWindows schannel 层连接关闭异常重试、更换网络、检查代理curl: (60) SSL certificate problem证书校验失败检查系统时间、证书链、考虑-k调试curl: (6) Could not resolve host域名无法解析检查 DNS、nslookup、系统 hosts 文件从我的实际经验看403 报错是最容易被误判的。很多人以为 403 就是没权限但其实接口方可能是在拦爬虫。curl 默认的 User-Agent 是类似curl/8.1.2的字符串服务端如果按 UA 特征做拦截很容易识别出这是命令行工具。你可以临时指定一个浏览器 UA 试试curl.exe -H User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 https://api.example.com/api我试过不少次改完 UA 之后 403 直接消失。当然如果服务器校验的是登录态或 Token改 UA 没用那就老老实实带 Cookie 或 Authorization 头。4.2 Windows 脚本中的 curl 实战要点这里顺便说一下如何把 curl 集成到 Windows 批处理和 PowerShell 脚本里因为单纯在命令行敲命令只是入门脚本化才是效率来源。批处理脚本.bat里的写法echo off curl.exe -s -o response.json -w HTTP_CODE: %%{http_code} https://api.example.com/api批处理里如果要用 curl 的变量输出百分号需要写成%%这是个很隐蔽的坑。-w参数可以自定义输出信息比如追加返回码、耗时curl.exe -s -o response.json -w code:%%{http_code} time:%%{time_total} https://api.example.com/apiPowerShell 脚本里我一般这样用$response curl.exe -s -w n%{http_code} https://api.example.com/api注意在 PowerShell 里调用 curl.exe 时返回的是一个字符串数组不是单个字符串。如果你要解析 JSON 响应可以先用-Join合并再转成对象$raw curl.exe -s https://api.example.com/api $json $raw -join n | ConvertFrom-Json如果是通过 cmd /c 调批处理记得关注%ERRORLEVEL%。curl 执行成功返回 0任何错误都返回非 0。脚本里判断请求是否成功不应该依赖输出内容而应该看退出码curl.exe -s -o response.json https://api.example.com/api if %ERRORLEVEL% NEQ 0 ( echo 请求失败 exit /b 1 )这个习惯能帮你避免“内容解析时才发现请求结果不是自己想要的”这种后知后觉。4.3 在 Windows 上处理换行符与编码问题Windows 原生文本文件的换行符是\r\n而很多接口返回的是\n你在终端里看到的 JSON 可能是一整行没有格式化。这个问题在 Windows 上尤其明显。我建议调整一下输出处理先把 curl 输出保存成文件再用文本编辑器或 PowerShell 处理。尽量不要直接在终端里复制粘贴 JSON 去格式化因为 Windows 控制台对 UTF-8 的显示、复制可能会有编码坑复制出来的内容可能带着乱码或者把换行符弄丢。如果想在终端里直接格式化 JSON可以配合 jq 使用。Windows 上没有自带 jq下载一个 jq.exe 放到任意目录并加入 PATH 即可curl.exe -s https://api.example.com/api | jq .这一招在排查接口返回时很有用尤其是当响应体是一大坨嵌套很深的 JSON 时格式化后的可读性天差地别。5. 我日常用 curl 时沉淀下来的一些经验5.1 给 Windows Terminal 用户的小配置建议如果你用 Windows Terminal我建议你做两件小事第一把终端默认代码页切到 UTF-8可以用chcp 65001或者直接修改注册表里的HKEY_CURRENT_USER\Console配置。第二别在配置文件里给curl设置 alias坚持写curl.exe确保无论你在哪个环境执行脚本行为都可预期。Windows Terminal 还支持自定义快捷键和上下文菜单比如把鼠标选中即复制打开这在复制长命令时非常舒服。我实操下来Windows Terminal 比传统 CMD 舒服很多建议你把日常命令行终端都往这个方向迁移。5.2 用 curl 做接口冒烟测试的小套路我习惯把某个接口的完整调用流程写成一个批处理脚本里头按顺序做这么几件事echo off set BASE_URLhttps://api.example.com echo [1] 检查服务是否存活 curl.exe -s -o NUL -w HTTP状态码: %%{http_code}n %BASE_URL%/health echo [2] 登录获取Cookie curl.exe -s -c cookie.txt -X POST %BASE_URL%/login -H Content-Type: application/json -d login.json echo [3] 用Cookie请求业务接口 curl.exe -s -b cookie.txt -H Content-Type: application/json %BASE_URL%/profile -o profile.json echo [4] 检查返回内容 type profile.json | find username注意第一行我用了-o NUL配合-w只输出 HTTP 状态码不输出响应体这样日志会比较干净。在 Windows 的 CMD 里丢弃输出的目标是NUL而在 Linux 里是/dev/null这个差异很基础但第一次跨平台用的人总容易写错。这套冒烟测试流程虽然简单但真的能帮我在五分钟内判断一个服务是死是活、登录是否正常、业务接口是否可用。你把它扩展成健康检查脚本或者是上线前的回归脚本完全够用。5.3 关于 -k 和临时绕过证书验证再啰嗦一句调试内部系统时为了省事直接加-k我干过不少次。但每次我都很清楚这只是权宜之计如果用-k之后接口能通我会顺手记下“证书链有问题”这个待办回头推进运维去修。因为互联网接口一旦被中间者攻击不加证书验证的请求等于裸奔。在 Windows 上schannel 后端的证书验证行为有时和浏览器不完全一致尤其是一些老服务器使用旧证书算法时调试过程会更痛苦但你也不要因为这个就长期依赖-k。正确做法是把内部系统的自签名证书导出来双击安装到 Windows 的“受信任的根证书颁发机构”存储里。装完之后curl 和浏览器都能正常访问不再需要-k。这个流程需要管理员权限装完可能需要重启终端才能生效。6. 进阶Windows 下让 curl 更好地为工作服务6.1 结合 PowerShell 管道与变量Windows 用户既然身处 PowerShell 环境自然要把 PowerShell 的管道能力用起来。下面这段脚本可以把 curl 输出转成 PowerShell 对象方便后续按字段筛选$raw curl.exe -s https://api.example.com/api/users $data $raw -join n | ConvertFrom-Json $data.users | Where-Object { $_.status -eq active } | Select-Object name, email这里容易失败的细节是curl.exe 在 PowerShell 里的输出是数组如果直接ConvertFrom-Json有时会报“无法处理因为输入不是字符串”。所以一定要先-join合并。这一步坑了很多人。6.2 一个完整的文件下载与断点续传场景Windows 上下载大文件尤其是需要反复重试的场景我给 curl 加两个参数curl.exe -L -C - -o bigfile.iso https://mirror.example.com/bigfile.iso --retry 5 --retry-delay 3这里-C -是断点续传从上一次中断的位置继续下载--retry 5是失败后最多重试 5 次--retry-delay 3是每次重试间隔 3 秒。我在 Windows 上下大文件基本都用这个组合比浏览器的下载管理器省心也比一些专业下载工具更容易脚本化。如果还要限制带宽避免下载时把公司网络占满curl.exe --limit-rate 500k -L -o bigfile.iso https://mirror.example.com/bigfile.iso--limit-rate 500k表示最高每秒 500KB。这个参数在 Linux 和 Windows 上都能用且行为一致。6.3 多请求并发的小技巧新版本 curl 支持--parallel参数可以同时发起多个请求。在 Windows 内置版本里如果版本较新可以这样curl.exe --parallel https://api.example.com/api/a https://api.example.com/api/b https://api.example.com/api/c并发请求做接口压测或者同时检查多个服务状态时比写循环一个接一个请求要高效得多。但要注意--parallel的响应输出是块状的不是严格按 URL 顺序排列脚本解析时要有点心理准备。如果你需要每个请求独立的输出文件最好配合-o一个一个指定curl.exe --parallel -o a.json https://api.example.com/api/a -o b.json https://api.example.com/api/b这种方法比串行循环节省大量时间。不过说实话真正的压测场景我一般不会用 curl会用更专业的工具但日常快速看多个接口是否存活--parallel已经够用了。7. 写在最后的几点实在建议我在这篇文章里把 Windows 上使用 curl 最核心的东西都串了一遍内置版本认识、PowerShell 别名区分、常用命令、引号转义、SSL 报错、脚本化处理和几个进阶技巧。如果你只记住三件事那我的建议是第一在 Windows 上写命令尽量用curl.exe别用curl这样可以避开 PowerShell 别名的干扰也让脚本跨环境执行更稳定。第二POST JSON 时多习惯用-d body.json从文件读请求体别在命令行里跟引号转义死磕。第三遇到 SSL 相关报错先看curl --version里是 Schannel 还是 OpenSSL再看系统时间最后才考虑-k临时绕过。这些都是我实际踩坑后的教训。尤其是 PowerShell 别名这个问题我当年刚切到 Windows 时明明敲的是 curl 却被 Invoke-WebRequest 接管一度以为系统坏了。现在回想起来其实只是名字冲突。但愿这篇文章能让你少走这些弯路。另外如果你平时的工作流里经常需要处理接口返回的 JSON我建议把 jq 这个工具也装上。Windows 上装 jq 解压一个 exe 放 PATH 就行比在终端里人眼盯着一长串 JSON 幸福得多。工具没有高低之分谁用着顺手就该用谁。curl 和 jq 组合起来就是一套非常轻量的 API 调试环境足够应付日常绝大多数场景。以后在 Windows 上看到 “curl” 这个词希望你脑子里跳出来的不是“又一个坑”而是“哦我知道该怎么用了”。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。