Express Middleware设置标头错误

时间:2017-10-10 02:09:46

标签: express middleware

我正在尝试为我的Express应用程序实现一个相当简单的中间件函数,它只是将useCache值添加到传递给主处理程序的请求对象中,但出于某种原因,我得到了一个{{ 1}}错误。

Can't set headers after they were sent

我已经读过大多数时候,如果错误是由中间件产生的,那是由于多次const cacheControl = (req, res, next) => { if (lastPulled === null) lastPulled = Date().getDay() req.useCache = Date().getDay() === lastPulled next() } app.use(cacheControl) app.get('/missions', (req, res) => { if (req.useCache) res.status(200).json({ result: cache }) fetch(dumpUrl) .then(data => data.text()) .then(result => { cache = result res.status(200).json({ result }) }) .catch(e => res.status(500).json({ result: e.message })) }) 调用,但这不适用于此,除非我遗漏了一些明显的东西。

当我从应用程序中删除next()中间件时,不再出现错误,但我无法弄清楚函数中的错误导致错误!任何指针都有帮助!

1 个答案:

答案 0 :(得分:1)

我猜它是因为res.json()两次开枪:

app.get('/missions', (req, res) => {
  if (req.useCache) res.status(200).json({ result: cache })

  fetch(dumpUrl)
    .then(data => data.text())
    .then(result => {
      cache = result
      res.status(200).json({ result })
    })
    .catch(e => res.status(500).json({ result: e.message }))
})

// if res.useCase is true, set headers and reply
if (req.useCache) res.status(200).json({ result: cache })

// then fetch and reply again (which generates the error)
fetch(dumpUrl)
    .then(data => data.text())
    .then(result => {
      cache = result
      res.status(200).json({ result })

将其更改为此以使用显式返回

app.get('/missions', (req, res) => {
  if (req.useCache) return res.status(200).json({ result: cache })

  return fetch(dumpUrl)
    .then(data => data.text())
    .then(result => {
      cache = result
      res.status(200).json({ result })
    })
    .catch(e => res.status(500).json({ result: e.message }))
})

错误的性质与执行此操作时类似:

问题



    function problem() {
        if (true === true) console.log('send problem')
        console.log('send garbage by accident')
    }
    console.log(problem())




溶液



    function solution() {
        if (true === true) return console.log('send solution')
        return console.log('send nothing')
    }
    console.log(solution())




return是退出函数的方法。您的问题是您的代码正在检查if条件,但之后继续通过它,因为一旦发现该条件,它就不会被告知停止。

编写函数的旧方式或简洁方法如下:

app.get('/missions', (req, res) => {
  if (req.useCache) {
    res.status(200).json({ result: cache })
  } else {
    fetch(dumpUrl)
      .then(data => data.text())
      .then(result => {
        cache = result
        res.status(200).json({ result })
      })
      .catch(e => res.status(500).json({ result: e.message }))
  }
})

如果没有else,它会执行它遇到的每个if语句,直到它到达函数的末尾,除非你使用return关键字作为提示在那里退出。

请注意,在return函数中使用.then()将解决承诺,如果有更多.then()个链接,它将无法退出上限。