首页 > 解决方案 > Express 及其 json 解析器出现“结束后写入”错误

问题描述

我正在尝试构建一个使用 Express 接受 JSON 输入的 API。这似乎很简单,但我得到了错误[ERR_STREAM_WRITE_AFTER_END]: write after end

我的(非常简化的)(TypeScript)代码如下:

import express from 'express';
const app = express();
const jsonParser = express.json();

app.use(async (req, res, next) => {
  // Common actions for all requests
  console.log('Raw request:', req);
  res.setHeader('Content-Type', 'application/json');
  await next();
  res.end();
});

app.post('/example', jsonParser, async (req, res) => {
  console.log('Parsed request body:', req.body);
  res.write('ok');
});

app.listen(3000);

当我发布一些 JSON(简单{"test":"test"})时,带有Content-Type: application/json127.0.0.1:3000/example,我的程序因“结束后写入”错误而崩溃。我尝试了以下事情:

  1. 如果我将 Content-Type 设置为其他内容(如 text/plain),它不会崩溃,但 JSON 未被正确捕获(我的日志“Parsed request body”显示一个空对象)。
  2. 如果我删除res.write('ok');,它也不会崩溃(并返回一个空字符串),但这意味着我无法返回东西,这是不可接受的。
  3. 如果我删除整个app.use(...)部分,它可以正常工作,但我真的希望能够对那里的所有路线进行一些预处理 +/- 后处理,所以这也不是一个令人满意的选择。

有什么我做错了,还是不可能做我想做的事,我应该坚持选择第 3 项?

标签: node.jsexpress

解决方案


好在意料之中error_ 您在关闭(或结束)它之后写入流。response

await next(); // <-- This is calling you next middleware
res.end(); // meanwhile this is executed and closes the stream

你可以这样做:

app.use(async (req, res, next) => {
  // Common actions for all requests
  console.log('Raw request:', req);
  res.setHeader('Content-Type', 'application/json');
  next();
});

app.post('/example', jsonParser, async (req, res) => {
  console.log('Parsed request body:', req.body);
  res.write('ok');
  res.end();
});

推荐阅读