通过Curl访问SSE端点时Jq无输出的原因排查
SSE端点curl+jq无输出的原因分析及解决
核心现象
- 单独执行
curl + sed可正常输出SSE返回的JSON内容,但追加jq '.summary'后无任何输出 - 本地搭建SSE测试服务器后,多种jq组合命令仍无法得到输出
- 用echo模拟单条SSE数据时,相同的
sed + jq命令可正常提取summary字段
根本原因
1. jq的默认缓冲机制
jq默认会**缓冲所有输入直到收到EOF(文件结束符)**才开始处理。但SSE是持续数据流,服务器会保持连接不断推送新数据,不会主动发送EOF,导致jq一直处于等待状态,永远不会输出结果。
而sed处理流数据时默认采用行缓冲,每收到一行就处理并输出,所以单独用sed能看到实时JSON内容。
2. SSE数据格式的潜在干扰
从hexdump输出可见,SSE返回的每条数据结尾是\n,而标准SSE格式是每条数据后跟两个换行符(\n\n)分隔。如果中间存在空白行,直接用sed替换data:后会出现空行,jq遇到空行无法解析为JSON时会静默丢弃错误输入,但这不是无输出的核心原因——缓冲机制才是关键。
解决方法
方法1:让jq采用无缓冲模式
给jq添加--unbuffered参数,强制行缓冲,让jq每收到一行就处理并输出:
curl -N --http2 -H "Accept:text/event-stream" --silent https://my_domain/stream/OyP1cEC3N7BTQrCsm3AHrTFAj5F5VKCH/notifications | sed 's/^data://' | jq --unbuffered '.summary'
注:sed正则改为^data://,确保只替换行首的data:,避免误替换JSON内部字符串。
方法2:用jq流模式直接处理SSE格式
无需sed,直接让jq处理SSE的data:前缀,同时开启无缓冲:
curl -N --http2 -H "Accept:text/event-stream" --silent https://my_domain/stream/OyP1cEC3N7BTQrCsm3AHrTFAj5F5VKCH/notifications | jq -n --unbuffered 'inputs | select(startswith("data:")) | .[5:] | fromjson | .summary'
解释:
-n:不读取标准输入首行,用inputs处理所有输入行select(startswith("data:")):过滤出SSE数据行.[5:]:去掉开头的data:fromjson:解析为JSON对象.summary:提取目标字段
方法3:调整sed的缓冲(可选)
部分环境下sed可能存在缓冲,可添加-u参数强制行缓冲,配合jq无缓冲:
curl -N --http2 -H "Accept:text/event-stream" --silent https://my_domain/stream/OyP1cEC3N7BTQrCsm3AHrTFAj5F5VKCH/notifications | sed -u 's/^data://' | jq --unbuffered '.summary'
内容的提问来源于stack exchange,提问作者Solonl
相关产品推荐
相关产品推荐

