根本原因是Node.js默认发送application/json或原始流,而PHP仅在Content-Type为x-www-form-urlencoded或multipart/form-data时自动解析到$_POST;需统一格式、编码与请求头。

Node.js 发送 POST 数据时 PHP 读不到 $_POST
根本原因不是“PHP 没收到”,而是 Node.js 默认发的是 application/json 或原始二进制流,而 PHP 只在 Content-Type: application/x-www-form-urlencoded 或 multipart/form-data 时自动解析进 $_POST 数组。
实操建议:
- 如果 Node.js 用
axios.post(url, { key: 'val' }),默认发 JSON —— PHP 端得用file_get_contents('php://input')手动读,$_POST为空 - 想让 PHP 自动填
$_POST,Node.js 必须发 URL 编码格式:key=val&key2=val2,并显式设置Content-Type: application/x-www-form-urlencoded - 用
querystring.stringify({ key: '中文' })处理值,它会自动encodeURIComponent,避免 PHP 端$_POST乱码或截断
中文参数在 PHP 里变问号或空字符串
本质是编码链断裂:Node.js 发送时没编码、HTTP 传输没声明编码、PHP 解析时没按 UTF-8 处理。
关键检查点:
立即学习“PHP免费学习笔记(深入)”;
- Node.js 端:确保
querystring.stringify()处理过数据(它生成的是 UTF-8 编码的字节序列) - HTTP 请求头必须带:
Content-Type: application/x-www-form-urlencoded; charset=UTF-8(注意分号后空格不能少) - PHP 文件本身保存为 UTF-8 无 BOM 格式(BOM 会导致 header 输出失败,间接影响
$_POST) - PHP 中不要用
iconv('GBK', 'UTF-8', $_POST['key'])去“转”——原始就是 UTF-8,强行转反而损坏
用 curl 或 Postman 能通,但 Node.js 死活不行
大概率是 Node.js 的请求构造漏了关键头或格式,而 curl/Postman 默认行为更“宽容”。
快速验证方式:
- 在 PHP 端加一行:
file_put_contents('/tmp/debug.log', print_r($_SERVER, 1) . "\n" . file_get_contents('php://input') . "\n\n", FILE_APPEND);,对比 curl 和 Node.js 的Content-Type、Content-Length、原始 body - Node.js 用
axios时别写headers: { 'Content-Type': '...' }却不配data:—— axios 会把对象自动转 JSON,覆盖你的意图 - 改用底层
http.request时,记得调用req.write(...)并req.end(),漏掉end()请求就卡住,PHP 根本收不到
PHP 收到数据但 $_POST 还是空,php://input 却有内容
说明请求体被 PHP 识别为非标准表单格式(比如 JSON、XML、纯文本),所以跳过 $_POST 填充流程。
这时不要硬调 $_POST,直接处理 php://input:
$raw = file_get_contents('php://input');- 如果是 JSON:
$data = json_decode($raw, true);,然后用$data['key'] - 如果是 URL 编码但没进
$_POST,可能是enable_post_data_reading = Off(极少见,查 php.ini) - 检查
post_max_size和max_input_vars是否过小 —— 特别当传大量字段时,PHP 会静默丢弃超出部分
$_POST 就成空数组。











