ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

curl -i 实战指南:学会看响应头,接口问题秒定位

curl -i 实战指南:学会看响应头,接口问题秒定位 先说个真实的事。上个月我帮同事排查一个接口问题前端页面一直报错后端日志全绿两个人都觉得是对方的锅。我在中间敲了一行curl -i https://api.example.com/user/info三秒钟定位了问题——响应头里Content-Type是application/octet-stream不是预期的application/json浏览器拿到二进制流不知道该怎么解析自然就白屏了。类似这种场景我遇到过太多次。所以现在只要有人问我 curl 最值得养成习惯的参数是什么我的答案永远是-i也就是--include。这篇文章就围绕curl -i展开它到底做了什么、输出该怎么看、和-I/-v/-D这几个长得像的兄弟参数有什么区别、实际排查问题的时候怎么用以及我在长期使用中踩过的一些坑。无论你是刚接触命令行的小白还是天天调接口的老手这篇应该都能给你点新东西。1. 调接口这些年我为什么把 -i 当成了肌肉记忆1.1 一次差点背锅的线上事故问题根本不在数据先把这个案例讲完整。那次是公司内部管理后台的登录功能异常前端拿到接口返回后一直提示登录失败请稍后重试后端同事查了半天日志发现请求都正常打到了服务业务逻辑也执行完了返回码是 200数据看着也对。两个人互相推了半天最后拉我过去协助。我做的第一件事就是加-i重新请求了一遍curl -i -X POST https://api.example.com/login \ -H Content-Type: application/json \ -d {username:admin,password:123456}输出长这样HTTP/1.1 200 OK Content-Type: application/octet-stream Content-Length: 521 Date: Fri, 14 Feb 2025 10:00:00 GMT Server: nginx/1.24.0 {code:0,message:success,data:{token:xxx}}问题一目了然响应体明明是 JSON 格式的字符串响应头却声明成了application/octet-stream。浏览器和 axios 这类前端库拿到响应后会严格按照Content-Type去解析内容。你要么把它当成二进制流处理要么干脆走通用逻辑——一旦遇到非预期类型很多前端库会直接走上报错误的那个分支。这个锅最后落到谁头上我就不说了。但这件事让我特别想强调一个观念调试接口的时候响应头和响应体是同一份信息的两面只看响应体等于只听了半句话。我后来排查任何接口问题习惯性带上-i原因就在这里——我不想再因为少看了一眼响应头而多花两个小时。1.2 curl -i 的原理把 HTTP 报文从黑盒变成透明curl -i做的事情从官方文档来说就一句话Include the response headers in the output。也就是在标准输出里把服务端返回的 HTTP 响应头原样打印出来。但这句话背后涉及一个很多人不太在意的知识点HTTP 报文本身是分两部分的。如果你抓过包或者看过 HTTP 规范就知道一次完整的 HTTP 响应大概长这样HTTP/1.1 200 OK Content-Type: application/json Content-Length: 34 Cache-Control: no-cache {code:0,message:success}从HTTP/1.1 200 OK开始到第一个空行结束这一段是响应头Headers空行之后是响应体Body。响应头是元数据描述这个响应的性质、编码、过期策略、服务器信息等等响应体是实际载荷也就是应用层真正关心的数据。大多数时候我们用 curl 都是为了拿响应体比如请求一个 API 看返回的 JSONcurl https://api.example.com/user/info默认情况下curl 只把响应体打印到终端响应头全部藏在暗处。这就是很多问题看不见的根源——服务端可能早就通过响应头告诉你出什么事了问题是你不让它说。-i的作用就是把那段藏起来的元数据也展示出来让你看到完整的 HTTP 报文。用个生活化的类比响应体就像快递包裹里的商品响应头就是快递单上的所有信息——寄件人、收件人、物流方式、是否保价、是否能退换。你说你收到一个包裹只看里面东西对不对那难怪有时候会困惑为什么我下单的是手机收到的却是个充电器因为快递单上早就写了发货仓库和商品规格你没看而已。-i这个参数的实现原理也比较简单curl 在内部解析完响应头之后不是直接丢弃而是把这段文本连同响应体一起交给输出模块。它不会改变请求行为不影响请求方法不改变请求头——纯粹是展示层的调整。这也是为什么我反复强调-i是一个零副作用的调试参数你可以放心大胆地把它加到任何 curl 命令里。2. 看懂 curl -i 的完整输出响应头里藏着什么信息很多人虽然用了-i但输出往终端一打眼睛直接盯到最后一行的 JSON 上中间那段响应头扫一眼就过了。这样用-i就浪费了。既然把响应头亮出来了就得学会读它。curl -i https://api.example.com/search?qcurl典型输出HTTP/1.1 200 OK Date: Fri, 14 Feb 2025 10:05:00 GMT Content-Type: application/json; charsetutf-8 Content-Length: 87 Connection: keep-alive Access-Control-Allow-Origin: * Cache-Control: no-cache Server: gunicorn/21.2.0 {results:[],total:0}我读这段响应头是有固定顺序的检查项不多但每个都有用。2.1 状态行HTTP 版本、状态码、状态短语第一行叫状态行Status Line格式是HTTP/版本号 状态码 状态短语。HTTP/1.1表示协议版本。HTTP/1.1 是目前互联网上最主流的版本HTTP/2 在 curl 输出里会显示成HTTP/2 200注意 HTTP/2 没有状态短语这个概念所以你可能看到HTTP/2 200后面直接换行这是正常的。200是三位数的状态码这是最重要的数据。它分为五类1xx信息性响应、2xx成功、3xx重定向、4xx客户端错误、5xx服务端错误。OK是状态短语人类可读的补充说明。404后面通常跟着Not Found502后面通常是Bad Gateway。很多新手会犯一个错误只看状态码是200就认为接口没问题。我在第一章节那个案例里已经讲过200只能说明请求被正常处理并返回了不代表内容就是对的。真正出问题的时候状态码能帮我们快速判断责任方状态码含义排查方向301/302资源被永久/临时移动看Location确认重定向目标401未认证看WWW-Authenticate检查凭证403禁止访问权限配置、IP 白名单、防盗链404资源不存在路径写错、网关路由规则429请求太频繁限流策略等待或降速500服务器内部错误后端日志、异常堆栈502网关收到无效响应上游服务是否挂掉、超时配置503服务不可用是否在重启、过载保护2.2 响应头字段逐个拆解哪些字段决定成败状态行下面是若干响应头字段格式统一是字段名: 值。我挑几个日常排查中出场率最高的说。Content-Type响应体媒体类型这是curl -i排查中最重要的字段之一。它的值告诉解析方响应体到底是什么格式。常见值包括application/json——JSON 数据接口联调最常见text/html; charsetutf-8——HTML 页面text/plain——纯文本application/octet-stream——二进制流常见于文件下载接口image/png、image/jpeg——图片资源multipart/form-data; boundary...——表单或分段上传响应注意charset参数。比如Content-Type: text/html; charsetutf-8charset表示字符集。如果服务端返回的是 UTF-8 编码的中文但charset声明成了gbk客户端就可能乱码。这个字段写错被坑过的前端同学不在少数。Content-Length响应体字节数表示响应体的长度单位是字节。这个字段有两个用途。一是做完整性校验如果响应体实际长度和Content-Length对不上说明传输过程中有截断可能是服务端没写完就关闭连接也可能是网关超时切断了流。二是用来判断响应是否为空Content-Length: 0说明没有响应体这在有些接口设计里是正常空结果的标识。有个细节如果响应头里同时有Transfer-Encoding: chunked那Content-Length通常不出现。chunked表示服务端边生成边发送无法预先知道总长度。看到Transfer-Encoding: chunked时别去检查Content-Length那是徒劳。Set-Cookie服务端种下的 Cookie登录类接口的响应头里经常出现这个字段。格式类似Set-Cookie: session_idabc123; Path/; HttpOnly; SameSiteLax它表示服务端要求客户端保存这个 Cookie后续请求带上它来维持会话。调试登录态时curl -i输出里有没有Set-Cookie、Expires、Max-Age、Domain设置得对不对直接决定你的会话能否建立。后面第四章我会专门用一个案例讲。Location重定向目标地址出现在3xx响应中告诉客户端你要的东西不在这里去这里拿。比如HTTP/1.1 302 Found Location: https://api.example.com/v2/user/info如果接口突然出现 302基本先看Location指到哪八成能找到原因。是 URL 从 http 跳 https是加不加尾部斜杠导致重定向还是网关给你指到了登录页Cache-Control缓存策略no-cache、no-store、max-age3600、private、public……这些值决定客户端和中间代理能不能缓存响应。调试缓存问题时这个字段是核心依据。比如明明改了后端代码但前端还是旧数据先看响应头Cache-Control是不是max-age86400——那是让浏览器一年不更新的节奏。Server服务端软件标识Server: nginx/1.24.0、Server: gunicorn/21.2.0泄露了一些服务端信息但更多时候它的价值是让你快速判断这个响应到底是谁生成的。经常有系统前面挂了 Nginx 后面是 Tomcat你看到Server: nginx就知道这个响应经过了反向代理只有Server: Tomcat或者自定义标识说明请求没走代理直连了后端。这个信息对排查网络拓扑很有用。Access-Control-Allow-Origin跨域相关浏览器做 AJAX 请求最常见的报错就是 CORS。如果响应头里没有Access-Control-Allow-Origin或者它的值不包含你的域名浏览器会直接拦截。用curl -i敲一下接口就能立刻验证是不是 CORS 问题——要注意curl 本身不受 CORS 限制所以 curl 能拿到数据说明服务端响应没问题问题出在浏览器端的安全机制上。2.3 空行响应头和响应体的分界线curl -i输出中响应头结束后会有一个空行然后才是响应体。这个空行不是排版好看它是 HTTP 协议规定的分隔符。解析 HTTP 报文时第一次遇到空行之前的都是头之后的全是体。手写过 HTTP 裸协议的应该深有体会你要自己拼请求头尾之间漏了空行服务端会直接给你丢回 400。用curl -i看到这个空行时也可以顺便判断响应头是否完整。正常的 HTTP/1.1 响应一定是头结束空行再读体如果空行迟迟不出现可能连接被异常中断了。3. -i、-I、-v、-D看响应头有四种姿势别选错很多人把-i、-I、-v、-D搞混尤其是-i和-I只差一个大小写踩坑的特别多。这四个参数都能让你看到响应头但底层逻辑完全不同用错了场合要么信息不够要么画蛇添足甚至可能让请求行为发生变化。3.1 -I大写 i发起的是 HEAD 请求不是 GET-I是--head的缩写它的作用是只获取响应头不获取响应体。实现方式是向服务端发一个HEAD请求HTTP 协议规定服务器收到HEAD请求后必须返回和GET一样的响应头但没有响应体。看几个关键区别参数请求方法是否显示响应头是否显示响应体curl -i URLGET默认是是curl -I URLHEAD是否协议上本就没有curl -v URLGET默认是更详细是curl -D - URLGET默认是是-I最大的问题是它改变了请求方法。有些服务器对HEAD请求的处理和GET不一样比如某些框架的HEAD路由没注册直接返回405 Method Not Allowed还有一些服务虽然支持HEAD但为了性能不执行真正的业务逻辑导致响应头里的Content-Length和实际GET返回的响应体长度不一致。所以我一直建议如果你是单纯想检查一个 URL 通不通、看看状态码和几个响应头字段用-I没问题速度快、省流量。但如果你要排查的是一个真实的业务接口是否正常返回数据请务必用curl -i而不是curl -I否则你看到的是 HEAD 的世界不是 GET 的世界。我有一次排查同事的接口问题他用-I测出来200跟我说接口没问题结果我用-i一测响应体里直接是异常堆栈——因为服务端 GET 路由里有一段代码崩了但 HEAD 请求压根没走到那段逻辑。3.2 -v小写 v全链路信息比 -i 多几个维度-v是--verbose的缩写它的信息量比-i更大。除了能显示响应头还能显示请求行GET /user/info HTTP/1.1请求头Host、User-Agent、Accept等握手阶段的细节Connected to ... port 443、ALPN, offering h2、SSL connection using TLSv1.3等重定向过程中的每一步耗时信息如果需要配合-w更精准看一段curl -v的典型输出开头* Trying 93.184.216.34:443... * Connected to api.example.com (93.184.216.34) port 443 * ALPN: offers h2 * ALPN: accepted h2 * TLS 1.3 (ne) using TLS_AES_128_GCM_SHA256 GET /user/info HTTP/1.1 Host: api.example.com User-Agent: curl/8.5.0 Accept: */*带*的行是 curl 的内部过程信息带的是请求头带的是响应头。-v适合排查连接层的问题——连不上、TLS 握手失败、HTTP/2 协商异常、DNS 解析不对。可以说-v是-i的超集那为什么我不总是用-v因为输出太啰嗦了。日常调接口只需要看响应头和响应体-i干净利落只有怀疑问题出在网络层、连接层时才上-v。这里说一句题外话网上很多教程喜欢让人用-v去排查一切我觉得这其实增加了噪音。所有*开头的行对不熟悉的人来说都是干扰源先看懂-i的输出再升级到-v学习曲线更平滑。3.3 -D大写 D把响应头落盘保存-D是--dump-header作用是把响应头写入指定文件。常用的写法是curl -D headers.txt https://api.example.com/user/info -o body.json这样响应头存到headers.txt响应体存到body.json两者分离适合需要长时间保留排查现场的场合。你也可以用-D -把响应头输出到标准输出效果类似-i但更纯粹——只输出响应头不混着响应体。我从实践角度给个选择建议只是肉眼快速看一下用-i明确不想发 GET 请求、只查头信息用-I怀疑 DNS、TLS、HTTP/2 等连接层问题用-v需要把响应头保存下来分析或留档用-D脚本里需要把响应头、响应体分开处理用-D配合-o4. 用 curl -i 排查实际问题的三个完整案例理论讲完上实战。我挑三个最有代表性的排查过程每个都是真实场景里反复出现的类型。4.1 场景一接口突然返回 401 Unauthorized是谁在拒绝我同事的定时任务脚本跑了一个月某天突然开始报错错误日志写着HTTP 401。他一头雾水代码没动过密钥没换过凭什么不让我访问我让他把那次请求原样打出来加上-icurl -i https://api.internal.example.com/report/daily \ -H Authorization: Bearer eyJhbGciOiJIUzI1NiIs...响应是HTTP/1.1 401 Unauthorized Content-Type: application/json Date: Fri, 14 Feb 2025 11:00:00 GMT WWW-Authenticate: Bearer realmapi, errorinvalid_token, error_descriptionThe access token expired Set-Cookie: session_id; Path/; ExpiresThu, 01 Jan 1970 00:00:00 GMT {error:unauthorized}关键信息全在那个WWW-Authenticate响应头里errorinvalid_tokenerror_description 写得很直白——token 过期了。再往前查这个脚本用的 token 有效期是 30 天上个月生成之后一直没更新跑满一个月正好过期。curl -i在这个案例里的价值有两个。第一401状态下服务端通常不会给你详细的业务错误 JSON但WWW-Authenticate头里往往藏着真正的拒绝原因。你不带-i默认只会看到一行{error:unauthorized}信息密度完全不够。第二Set-Cookie把旧的 session 值清空到 1970 年 1 月 1 日这其实在告诉你这个会话我已经不认了你重新登录吧。补充一个点如果你遇到的 401 响应头里只有WWW-Authenticate: Basic realm...而且响应体的 JSON 是标准错误格式那大概率是请求头里的Authorization格式写错了或者压根没传。Bearer和Basic是两种最常见的认证方案前者用 token后者用用户名密码的 Base64 编码别混用。4.2 场景二接口文档写着访问 /v2/user/info实际却返回 302数据去哪了有次联调我按接口文档请求/v2/user/info结果 curl 只输出了一小段内容看起来像是个跳转提示页。我立刻重来一遍带上-icurl -i https://api.example.com/v2/user/infoHTTP/1.1 302 Found Date: Fri, 14 Feb 2025 11:30:00 GMT Content-Type: text/html; charsetutf-8 Location: https://api.example.com/login?redirect/v2/user/info Content-Length: 0真相在Location里接口文档里的路径没错但网关层配置了未登录访问需要跳转登录页。所以这个 302 不是接口搬家是权限拦截。排查到这里问题就从为什么数据不对变成了为什么被判定为未登录——八成是请求少了Cookie头或者Authorization头。如果我要追查重定向之后的最终响应怎么办curl默认不会自动跟随重定向你需要加-Lcurl -i -L https://api.example.com/v2/user/info加上-L后 curl 会自动请求Location指到的地址直到拿到非 3xx 响应或到达最大跳转次数。这时候-i会打印出重定向链上每一步的响应头你就能看清楚完整链路。我排查跳转类问题时基本上是-i -L固定组合。要特别提醒的是有些 307/308 重定向会带着请求体和请求方法一起转而 301/302 按规范其实允许把 POST 变为 GET不同实现不完全一致。用curl -i -L观察状态码变化时如果发现方法变了导致后续请求失败可以配合--post301、--post302、--post303等参数去控制 post 行为也可以用--location-trusted让重定向后的请求保留认证头。这些组合参数虽然不如-i常用但遇到的时候非常救命。4.3 场景三登录接口 Set-Cookie 没问题但后续请求就是不带 Cookie这是前后端联调里的高发问题登录接口调用成功服务端也返回了Set-Cookie但下一个请求接口时后端说收不到会话。前端同学百思不得其解。先用 curl 复现登录看响应头curl -i -X POST https://api.example.com/auth/login \ -H Content-Type: application/json \ -d {username:test,password:123456}HTTP/1.1 200 OK Content-Type: application/json Set-Cookie: sid8f2a1c...; Path/api; ExpiresFri, 21 Feb 2025 11:00:00 GMT; HttpOnly Content-Length: 52 {code:0,message:login success}注意到没有Set-Cookie里有个Path/api。如果这个登录接口路径是/auth/login而 Cookie 的 Path 只覆盖/api那客户端访问/user/info时浏览器根本不会带上这个 Cookie因为/user/info不在/api路径范围内。用一个带 Cookie 保存的 curl 命令验证一下curl -i -c cookies.txt -b cookies.txt https://api.example.com/user/info-c让 curl 把服务端返回的 Cookie 写入本地文件-b让 curl 从本地文件读取 Cookie 附加到请求中。看第二个请求的响应头如果还是 401 或者Set-Cookie又出现一次基本就是 Cookie 的 Path、Domain 设置有问题。比如Domain设成了example.org但请求的是www.example.orgCookie 也带不上来。这里再补一个常见坑Cookie 属性里的SameSite。如果服务端返回的是SameSiteStrict跨站请求就不会带 Cookie。调试时要留意Set-Cookie里的 SameSite 属性和Secure只在 HTTPS 下携带属性。很多为什么登录态时有时无的问题最后都是这些属性在捣乱。5. 高级组合技与翻车现场curl -i 的正确打开方式-i单独用很简单但它真正的威力在于和其他参数组合。同时组合使用也给了一些可预见的坑。我把高频翻车点一起讲了省得大家再走弯路。5.1 常用组合技从菜鸟到老手的命令行进化组合一curl -i -s——静默模式下去掉进度条只留结果默认的 curl 在执行时会把进度条打到 stderr你和-i配合时如果只关心头部和响应体可以加-ssilent静默输出curl -is https://api.example.com/health这样输出干净没有那些实时跳动的进度百分比适合脚本里抓取和分析输出。组合二curl -i -w \n——结尾强制换行有时候响应体最后一个字符后面没有换行符和终端提示符挤在一起看着难受。用-w自定义输出格式在末尾追加一个换行curl -i -w \n https://api.example.com/health-w还能写更多内容比如提取耗时和状态码curl -i -w \n\n时间: %{time_total}s 状态码: %{http_code} 大小: %{size_download} 字节\n \ https://api.example.com/slow-api给运维同学提个醒监控接口响应耗时的时候可以直接用-w提取%{time_total}不用单独写探针脚本。组合三curl -i -o /dev/null——只看响应头如果你想看响应头但不需要把响应体刷屏到终端可以把响应体丢弃到/dev/nullcurl -i -o /dev/null https://api.example.com/health输出里就只剩响应头响应体被丢了。有人问这和-I有什么区别区别大了-I发的是 HEAD 请求这个组合发的还是 GET 请求服务端实打实执行了业务逻辑响应头信息量更真实只是我们不把响应体打出来而已。组合四curl -i -H Accept: application/json——强制指定响应格式有些服务端会根据请求头里的Accept决定返回 HTML 还是 JSON。加了-H指定Accept: application/json再用-i看响应头确认返回的Content-Type是否是application/json这是联调 RESTful 接口的基本功。组合五curl -i -d {key:value}—— POST 接口调试标准姿势curl -i -X POST https://api.example.com/items \ -H Content-Type: application/json \ -d {name:测试,price:99.9}注意-d会自动把请求方法设为 POST所以-X POST其实可以省略。但我还是习惯显式写出来减少阅读成本。POST 调试最容易出事的就是响应头里没有Content-Type: application/json或者返回了302去登录页-i全都看得清清楚楚。5.2 翻车现场curl -i 的常见坑坑一Content-Length和实际内容对不上前面说过curl -i能看到Content-Length。有时候你发现Content-Length是 100但实际响应体拉下来只有 80 字节然后 curl 报transfer closed with outstanding read data remaining。这说明响应被截断了。常见原因上游服务异常崩溃连接提前断开反向代理的proxy_read_timeout太短等不到上游返回完整数据就掐断了服务端代码里提前response.end()却没写完数据这种问题单靠-i能发现、能定位到传输层有问题具体在哪一环还要配合-v看连接信息或者看服务端访问日志。坑二响应体是 gzip 压缩格式终端输出一堆乱码有些服务端返回响应头Content-Encoding: gzip如果你请求时没带Accept-Encoding: gzip一般服务端会返回原始内容。但如果服务端不管三七二十一就是强制压缩有的 CDN 网关会这么干curl 默认情况不会自动解压你就在终端看到一堆二进制乱码。这时要加--compressedcurl -i --compressed https://api.example.com/datacurl 在收到响应后自动解压 gzip/deflate/br 编码的响应体。注意--compressed还会在请求头里自动追加Accept-Encoding告诉服务端我支持压缩所以配合-i看到响应头里的Content-Encoding: gzip是正常的响应体已经是解压后的内容了。坑三脚本里解析-i的输出被\r坑了这个坑非常隐蔽。HTTP 协议里响应头每一行是以\r\n结尾的而不是平时 Unix 文本的\n。你用curl -i拿到输出在终端肉眼看不出区别但如果你用它写脚本比如curl -is https://api.example.com/health | head -1输出的第一行末尾会自带一个回车符\r。你在 shell 变量里存下来再跟200做比较咋比都不对其实是因为\r混在字符串里。我踩过这个坑之后现在写脚本会加个管道清理curl -is https://api.example.com/health | sed s/\r$//或者更保险的做法是脚本里不要解析-i的完整输出改用-D把响应头写到临时文件再逐行处理。这样\r问题就更容易控制。坑四超时参数不配-i遇到卡住的接口就把你挂在那默认情况下curl 的连接超时和总超时都没有硬性限制如果服务端一直不响应你的终端就卡住了。排查接口的时候更容易遇到这个情况——服务端线程池满了你的请求排在队列里curl 就不动了。加超时是必须的curl -i --connect-timeout 5 --max-time 15 https://api.example.com/slow--connect-timeout限制建连时间--max-time限制整个请求的总时间。超时后 curl 会报错退出配合-i -w %{http_code}你至少知道请求根本没拿到响应而不是干瞪眼。坑五响应体过大刷屏登录接口还好如果是文件下载或大数据量接口-i连着响应体一起噼里啪啦打到终端终端可能卡死。这种情况下用前面提过的-o把响应体写到文件curl -i -o response.json https://api.example.com/large-data-i照样把响应头打印到终端供你检查响应体安静地写到文件里两不耽误。5.3 给脚本党的一句私房话自动保存响应头别傻傻 parse 大输出最后补一个脚本场景的建议。如果你在写自动化检查脚本希望拿到状态码、拿到响应体、拿到某个响应头字段最佳实践不是把curl -i的整个输出抓下来正则匹配而是这样curl -s -D /tmp/headers.txt -o /tmp/body.json https://api.example.com/health HTTP_CODE$(awk NR1 {print $2} /tmp/headers.txt) CONTENT_TYPE$(grep -i ^Content-Type: /tmp/headers.txt | tr -d \r | awk {print $2})脚本里用-D和-o把头和体分别落盘后续提取字段干净利落也不用担心\r的干扰。命令是给人看的脚本是给机器跑的人类可读性和机器可解析性是两码事。我在实际工作中已经形成了这样的肌肉记忆只要请求一个接口并想确认它的真实状态手先敲的是curl然后半秒内跟上-i。这个参数没有副作用、不改变请求行为、不增加服务端负担纯粹是让本该看到的信息不再被藏起来。从那次背锅事件之后我团队里的同事也都被我带出了这个习惯排查接口问题的时间平均下来确实短了不少。如果你之前一直只用默认 curl 拿响应体我建议你从下一个接口开始试着给每个调试命令加一个-i。先习惯看状态行再学会瞄一眼Content-Type和Content-Length最后自己遇到问题的时候自然会想到去读Location、Set-Cookie、WWW-Authenticate这些响应头字段。等哪一天你不用查文档、看一眼响应头就能猜出问题在哪一环的时候你就知道这个习惯有多值钱了。
返回列表