Express 中间件设置 Header 错误
Express Middleware Setting Header Error
我正在尝试为我的 Express 应用程序实现一个相当简单的中间件功能,它只是向传递给主处理程序的请求 object 添加一个 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 })
将其更改为此以利用显式 return
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()
,它不会从上层范围退出。
我正在尝试为我的 Express 应用程序实现一个相当简单的中间件功能,它只是向传递给主处理程序的请求 object 添加一个 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 })
将其更改为此以利用显式 return
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()
,它不会从上层范围退出。