为什么Telegram机器人webhook推送时服务端收到空POST请求?
问题根因
PHP 的 $_POST 超全局变量仅能解析 Content-Type 为 application/x-www-form-urlencoded 或 multipart/form-data 的 POST 请求。而 Telegram Webhook 推送的是 JSON 格式的原始 payload,请求头的 Content-Type 为 application/json,不会被 PHP 自动解析到 $_POST 中,所以你打印的日志里 POST 字段为空。另外日志中 HTTP_USER_AGENT 为空属于正常情况,Telegram 官方的回调请求本身就不会携带 User-Agent 头。
解决方法
从 PHP 内置的 php://input 流中读取原始请求体,即可获取到 Telegram 推送的 Update 对象内容,修改后的日志代码参考如下:
$file = dirname(__FILE__) . '/telegram-log.txt'; $entry = (object)array(); $entry->date = date("r"); $entry->GET = $_GET; // 读取Telegram推送的原始JSON内容 $rawPost = file_get_contents('php://input'); $entry->RAW_PAYLOAD = $rawPost; // 可直接解析为数组使用 $entry->UPDATE_DATA = json_decode($rawPost, true); $entry->POST = $_POST; $entry->REQUEST = $_REQUEST; $entry->HTTP_USER_AGENT = $_SERVER['HTTP_USER_AGENT'] ?? ''; $entry->REMOTE_ADDR = $_SERVER['REMOTE_ADDR']; file_put_contents($file, json_encode($entry, JSON_UNESCAPED_UNICODE) . PHP_EOL, FILE_APPEND | LOCK_EX);
额外排查点
如果修改后还是拿不到内容,可以检查以下配置:
- 确认你设置的 Webhook 地址没有配置 301/302 跳转规则(比如HTTP强制跳HTTPS、域名带www跳转不带www),跳转过程会丢失POST请求的body
- 如果你用了CDN、反向代理服务,确认代理层没有丢弃原始POST内容,也没有篡改请求头
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

