【问题标题】:cant send response after setting status设置状态后无法发送响应
【发布时间】:2019-08-19 14:16:26
【问题描述】:

我在我的快递中创建了一条路线,在提交时处理表单。
当表单流程遇到错误或问题时,我正在尝试设置状态并向客户端发送响应。
我在前端使用FormData(),在后端使用formidable
这是我试图处理回调方法中的错误的方法:

if (err) {
      res.status(500) // i have tried different status-codes !
      .send(`error on parsing : ${err}`)
      .end();      
}

问题是:
1_ 如果我设置了大多数状态代码(几乎所有状态代码,除了 200 之外),然后我得到一个响应说请求失败,状态代码为 500(或我设置的其他代码)并且 .send() 方法发送的数据不是在客户端收到

2_ .send() 带或不带 .end() 不会停止其余代码的执行,因为如果遇到错误,我会尝试在回调中结束响应,否则最后会出现 200 状态- 发送代码,代码执行到结束并到达结束,它尝试再次设置状态,当它们被发送到客户端时我得到错误无法设置标题

我已尝试使用不同的方法设置状态码或以其他方式发送响应。
我在网上搜索,我发现正确的方法是 res.status().send() 并且我做得正确,但是我遇到了问题。

这是我的代码(如果你需要我可以粘贴完整的代码):

app.post("/upload", (req, res) => {
  var form = new formidable.IncomingForm();
  form.on("error", err => {
    if (err) {
      res
        .status(500)
        .send(`Error on formidable : ${err}`)
        .end();
        console.log('continued');
    }
  });


  form.encoding = "utf8";
  form.uploadDir = "./uploadedFiles/";
  form.maxFileSize = 2000 * 1024 * 1024;
  form.parse(req, (err, fields, files) => {
    if (err) {

      res.status(500)
      .send(`error on parsing : ${err}`)
      .end();

    }
 // code continues with same style , methods with error handling in call backs  
//at the end of code :  
res.status(200).send("form successfully Submitted !");
}

客户端代码的“获取响应”部分:

try {
      let response = await axios.post("/upload", FD, {
        "Content-Type": "multipart/form-data"
      });
      console.log(response);

      $("#res")
        .css("display", "block")
        .text(response.data);
      $("#spinnerbox").css("display", "none");
    } catch (error) {
      $("#res")
        .css("display", "block")
        .text(error);
      console.log("Catched Error");
    }

我希望当我设置状态时我也能够发送响应。 (因为我搜索 res.status().send() 应该是正确的)。
我会很感激你的帮助。

【问题讨论】:

    标签: javascript node.js express http formidable


    【解决方案1】:

    您最好的解决方案是使用 try 和 catch 块然后抛出新错误 并创建错误中间件,然后您可以设置状态代码并使用错误调用下一步

    app.get('/route', (req, res, next) => {
      try {
        // do something
        if ('something failed') {
          throw new Error('error message!');
        }
      } catch (err) {
        next(err);
      }
    });
    
    // or if you want to set the status code
    
    app.get('/route', (req, res, next) => {
      try {
        // do something
        if ('something failed') {
          res.status(500);
          const error = new Error('error message!');
          next(error);
        }
      } catch (err) {
        next(err);
      }
    });

    【讨论】:

    • 欢迎来到 SO,答案看起来不错,但在我们的代码标准中保持质量很重要。您应该编辑以添加选项卡/空格以使代码可读。请记住,只提交一个您乐于在您自己的代码库上投入生产的答案。
    【解决方案2】:

    您也可以使用.josn 回复。

    200

    return res.status(200).json({ msg: 'SUCCESS' });
    

    400

    return res.status(400).json({ error: 'ERROR' });
    

    在您的情况下,您遇到了错误 错误:发送到客户端后无法设置标头

    当您的服务器返回单个请求的多个响应时,它就出现了 例如。

    // Incorrect Example
    if(something) {
      res.status(200).json({ msg: 'SUCCESS' }); 
    } 
     res.status(400).json({ error: 'ERROR' });
    
    

    在上面的代码中,一旦条件满了,它就会给出200,而在其他情况下,它会给出400,这里有2次响应发送会发生这样的错误(错误:不能在发送到客户端后设置标题

    为避免此类错误,您需要在响应之前添加关键字return

    // Correct Example
    if(something) {
     return res.status(200).json({ msg: 'SUCCESS' }); 
    } 
    return res.status(400).json({ error: 'ERROR' });
    
    

    【讨论】:

    • 按照您解释的方式,在客户端,它指向 Try Catch 语句中的错误,我在 catch 块中收到此消息:错误:请求失败,状态码为 500
    • 以上解释仅适用于nodeJs
    • 我正在使用nodeJS和express,通过axios异步获取结果
    • 我建议先从后端添加适当的错误处理,然后再去客户端
    • 我现在正在尝试这个:return res .status(500) .json({msg:error on parsing : ${err}}).end();实际上,在发送状态后没有发送响应,但是如果状态为 200 或...,状态和响应都发送,是否有可能状态代码停止其余的响应?
    猜你喜欢
    • 2019-04-24
    • 2014-01-27
    • 2012-09-28
    • 1970-01-01
    • 2011-01-23
    • 2015-11-07
    • 1970-01-01
    • 1970-01-01
    • 2021-02-23
    相关资源
    最近更新 更多