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

后端POST请求后出现Cannot set headers after they are sent to the client错误求助

Fixing "Cannot set headers after they are sent to the client" Error

Hey there! Let's break down what's causing this error and fix it step by step.

What's the Issue?

The error Cannot set headers after they are sent to the client happens because you're sending two separate HTTP responses for a single request. HTTP rules state that one request can only have one response—once you call res.send() or res.json(), the response is already sent to the client, and any subsequent attempts to send another response will throw this error.

Looking at your code:

  • You send a response with res.send() inside the db.query callback
  • You also send another response with res.json() inside the imageFile.mv callback
    These two operations run asynchronously, so whichever finishes first will send the response, and the second one will trigger the error.

Solution: Ensure Only One Response per Request

We need to restructure your code so that all required operations (file upload + database insert) complete first, then send a single response. Here are two clean ways to do this:

Option 1: Nested Callbacks (Simple & Straightforward)

We'll first handle the file upload, then run the database insert once the upload succeeds, and send the response only after both operations are done.

app.post('/upload', function (req, res) {
  let imageFile = req.files.file;

  // Step 1: Upload the file first
  imageFile.mv(`${__dirname}/public/${req.body.filename}.jpg`, function (err) {
    if (err) {
      // Send error response and exit if upload fails
      return res.status(500).send(err);
    }

    // Step 2: File upload succeeded, now insert into database
    const photoUrl = `http://localhost:8000/public/${req.body.filename}.jpg`;
    const data = { PhotoName: photoUrl };
    const sql = 'insert into photo set ?';

    db.query(sql, data, (err, result) => {
      if (err) {
        // Send error response if database insert fails
        return res.status(500).send(err);
      }

      console.log(result);
      // Step 3: All operations done, send single response
      res.json({
        type: 'POST',
        PhotoName: photoUrl,
        file: `public/${req.body.filename}.jpg`
      });
    });
  });
});

Option 2: Async/Await (Cleaner & More Readable)

If you prefer modern JavaScript syntax, use async/await to handle asynchronous operations like synchronous code:

app.post('/upload', async function (req, res) {
  try {
    const photoFilename = req.body.filename;
    const photoUrl = `http://localhost:8000/public/${photoFilename}.jpg`;

    // Wrap file upload in a Promise to use await
    await new Promise((resolve, reject) => {
      req.files.file.mv(`${__dirname}/public/${photoFilename}.jpg`, (err) => {
        err ? reject(err) : resolve();
      });
    });

    // Wrap database query in a Promise to use await
    await new Promise((resolve, reject) => {
      const data = { PhotoName: photoUrl };
      const sql = 'insert into photo set ?';
      db.query(sql, data, (err, result) => {
        err ? reject(err) : resolve(result);
      });
    });

    // All operations succeeded, send single response
    res.json({
      type: 'POST',
      PhotoName: photoUrl,
      file: `public/${photoFilename}.jpg`
    });
  } catch (err) {
    // Catch any errors from upload or database and send error response
    res.status(500).send(err);
  }
});

Key Changes Made:

  • Removed duplicate response calls (res.send() and res.json() are now combined into one)
  • Ensured operations run in sequence (file upload first, then database insert) so we only send a response once all work is done
  • Added proper error handling for both operations to avoid unexpected code execution

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:12:43