Node.js流写入表单数据报错:TypeError: Invalid non-string/buffer chunk
解决Node.js Stream写入表单数据时的
TypeError: Invalid non-string/buffer chunk问题 首先,咱们先拆解你遇到的错误核心原因:你给fs.createWriteStream设置了objectMode: true,但却往里面写入了字符串(通过JSON.stringify转换后的结果)。objectMode这个配置是用来让流支持直接写入JavaScript对象的,而默认模式下(objectMode为false),流只接受字符串或Buffer类型的数据——这两者的矛盾直接导致了这个错误。
接下来,咱们一步步解决问题,同时梳理排查思路:
1. 修正流的配置与写入逻辑
首先去掉objectMode: true,换成你真正需要的flags: 'a'(追加模式,避免每次提交覆盖之前的问卷数据),同时优化流的错误处理逻辑,避免程序崩溃:
修改后的Post路由代码:
app.post('/submit-form', function(req, res) { // 1. 从req.body获取表单数据(bodyParser已经帮你解析好了urlencoded格式) const formData = req.body; console.log('收到问卷数据:', formData); // 2. 把数据转成字符串,加上换行符方便后续查看每条记录 const fileContent = JSON.stringify(formData) + '\n'; // 3. 创建追加模式的写入流,去掉objectMode配置 const stream = fs.createWriteStream("Focus.txt", { flags: 'a' }); // 4. 处理流的错误事件(非常重要,避免写入失败导致程序崩溃) stream.on('error', (err) => { console.error('写入文件失败:', err); res.status(500).send('提交失败,请稍后重试'); return; }); // 5. 写入数据并结束流,写完后再渲染表单页面 stream.write(fileContent, () => { stream.end(); res.render('Form.html'); }); });
2. 修正HTML表单的Action路径
你之前把表单的action设为/FunFun.js,这很容易和静态文件路由(express.static)冲突,导致请求被当成静态文件处理而不是路由。建议改成更清晰的路由路径,比如/submit-form:
<form action="/submit-form" method="post" style="border : 2px solid black;"> <!-- 你的表单内容 --> <input type="submit" value="submit"> <input type="reset" onClick="resetB()"> </form>
3. 排查思路复盘(新手必备)
如果你以后再遇到类似问题,可以按这个顺序排查:
- 检查数据类型与流配置是否匹配:流的
objectMode开启时只能写对象,关闭时只能写字符串/Buffer,别搞混 - 确认表单数据的获取位置:POST表单的数据在
req.body里(需要bodyParser中间件),req.params是用来拿路由参数的(比如/user/:id里的id),别用错地方 - 确认文件写入模式:如果需要追加数据,一定要加
flags: 'a',默认是覆盖模式 - 处理错误事件:流、文件操作都可能出错,一定要监听
error事件,否则程序会直接崩溃 - 检查路由与静态文件的冲突:避免把路由路径设成和静态文件同名,否则express会优先匹配静态文件
另外,你之前尝试的fs.appendFile其实是可行的,只是当时错误地用了req.params.value来获取表单数据,换成req.body就能正常工作——如果只是简单的追加写入,fs.appendFile比手动创建流更简洁,比如:
app.post('/submit-form', function(req, res) { const fileContent = JSON.stringify(req.body) + '\n'; fs.appendFile('Focus.txt', fileContent, function(err) { if (err) { console.error('写入失败:', err); res.status(500).send('提交失败'); } else { console.log('数据已保存'); res.render('Form.html'); } }); });
内容的提问来源于stack exchange,提问作者JPho
相关产品推荐
相关产品推荐

