快递中间件设置标头错误

快递中间件设置标头错误

问题描述:

我试图实现一个相当简单的中间件功能,我的快递应用程序只是将useCache值添加到传递给主处理程序的请求对象,但由于某种原因,我得到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()电话,但在这里并不适用,除非我失去了一些东西明显。

当我从应用程序中删除cacheControl中间件时,不再有错误,但我无法弄清楚函数中的错误是什么造成的!任何指针都很有帮助!

我猜这是因为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关键字作为提示退出。

请记住,在.then()函数中使用return函数将解决该承诺,如果链接更多.then(),它将不会退出上方范围。