You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js向PHP服务器上传lumi文件失败问题排查

文件上传问题排查:Node.js到PHP的JSON文件上传失败

问题描述

我用Node.js向PHP服务器上传文件,图片文件可正常上传,但名称含“lumi”的JSON格式文件上传失败——请求返回200、文件名显示正常,但服务器并未写入文件。

图片上传的Node.js代码

const filePath = `${desktopDir}/ai2html-output/${individualFile}`;
const formFileUpload = fs.readFileSync(filePath);

// stream file
let buff = new Buffer(formFileUpload);
let base64data = buff.toString('base64');

form.append('file', base64data);
form.append('name', individualFile);

axios.post(API_ENDPOINT, form)
.then(res => console.log(res))

图片上传对应的PHP代码

$data = file_get_contents('php://input');
$postData = $_POST['file'];
$postName = $_POST['name'];

file_put_contents('./data/raws/' . $postName, base64_decode($postData));

lumi文件上传的Node.js代码(失败版本)

const filePath = `${desktopDir}/lumi/${fileName}`;
const formFileUpload = await fs.promises.readFile(filePath, { encoding: "utf-8" });

const lumiForm = new FormData();

lumiForm.append('file', formFileUpload);
lumiForm.append('name', fileName);

axios.post(API_ENDPOINT, lumiForm)
  .then(res => console.log(res));

lumi文件对应的PHP代码

if( strpos($postName, "lumi") !== false ) {
        file_put_contents('./data/lumi-templates/' . $postName, $postData);
        echo $postData;
}

错误原因分析

  1. FormData请求头未正确设置
    用axios发送FormData时,必须让axios自动生成multipart/form-data请求头(包含正确的边界符),否则PHP无法正确解析FormData中的字段,导致$_POST['file']可能为空。

  2. 数据处理逻辑不一致
    图片上传时你将文件转成base64后传递,PHP端做了解码;但lumi文件直接传utf-8文本,PHP端未做对应处理,且如果FormData解析失败,$postData会是空值,自然无法写入文件。

  3. 潜在的目录权限/存在性问题
    若./data/lumi-templates/目录不存在,或PHP进程没有写入权限,file_put_contents会静默失败(返回false),但请求仍会返回200。

修正方案

修正后的Node.js代码(lumi文件上传)

const filePath = `${desktopDir}/lumi/${fileName}`;
// 统一用Buffer读取,转base64和图片上传逻辑保持一致
const formFileUpload = await fs.promises.readFile(filePath);

const lumiForm = new FormData();
lumiForm.append('file', formFileUpload.toString('base64'));
lumiForm.append('name', fileName);

// 关键:让axios自动处理FormData的请求头
axios.post(API_ENDPOINT, lumiForm, {
  headers: lumiForm.getHeaders()
})
.then(res => console.log(res))
.catch(err => console.error(err));

修正后的PHP代码

// 先确保目标目录存在,不存在则创建
$lumiDir = './data/lumi-templates/';
if (!is_dir($lumiDir)) {
    mkdir($lumiDir, 0755, true);
}

// 避免未定义索引错误,先判断字段是否存在
$postData = $_POST['file'] ?? '';
$postName = $_POST['name'] ?? '';

if( strpos($postName, "lumi") !== false && !empty($postData) ) {
    // 和图片上传逻辑统一,做base64解码
    $result = file_put_contents($lumiDir . $postName, base64_decode($postData));
    // 调试用:查看写入结果
    if ($result === false) {
        echo "文件写入失败";
    } else {
        echo $postData;
    }
} else {
    echo "缺少文件数据或文件名不符合要求";
}

额外排查点

  • 检查PHP配置中的post_max_size和upload_max_filesize,确保文件大小未超过限制
  • 在PHP中添加var_dump($_POST);,确认file和name字段是否正确传递
  • 确认./data/lumi-templates/目录的权限,设置为755确保PHP进程可写入

内容的提问来源于stack exchange,提问作者FabricioG

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 06:48:25