Express中间件(使用app.use):发送后无法设置标头

时间:2017-09-13 08:16:47

标签: node.js express

我正在研究Express.js中间件,无论何时请求.xcss文件,都会编译该文件并返回.css样式表。 正常工作,但我仍然收到控制台错误“错误:发送后无法设置标头。”

这对我来说不是一个新错误,但这是我第一次不知道如何解决它。我不确定为什么要为.xcss GET请求发送两个响应(如果这甚至发生了什么)。 res.send之前的res.setHeader没有任何区别。

所有相关代码如下:

start.js:

const express   = require('express')
const app       = express()
const path      = require('path')
const xcss      = require('../lib/middleware')
const publicDir = path.join(__dirname, 'public')

app.use(xcss())
app.use(express.static(publicDir))

app.get('/', (req, res) => {
    res.sendFile('index.html')
})

app.listen(3000)

middleware.js:

const path     = require('path')
const compiler = require('./compiler')

module.exports = function(options) {
    return function(req, res, next) {
        const relativePath = req.url
        const absolutePath = path.join(options.src, relativePath)
        const fileExtension = path.extname(relativePath)

        if (fileExtension === '.xcss') {
            const css = compiler.compile(absolutePath)
            res.setHeader('Content-Type', 'text/css')
            console.log('>>> BEFORE')
            res.send(css) // <----- The offending line.
            console.log('>>> AFTER')
        }

        next()
    }
}

的index.html:

<!DOCTYPE html>
<html>
    <head>
        <link href="css/style.xcss" rel="stylesheet">
    </head>
</html>

console.log(使用摩根记录器):

::1 - - [13/Sep/2017:08:07:16 +0000] "GET / HTTP/1.1" 304 - "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36"
>>> BEFORE
>>> AFTER
::1 - - [13/Sep/2017:08:07:16 +0000] "GET /css/style.xcss HTTP/1.1" 304 - "http://localhost:3000/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36"
Error: Can't set headers after they are sent.
    at SendStream.headersAlreadySent (D:\Node.js\zigrid\node_modules\send\index.js:402:13)
    at SendStream.send (D:\Node.js\zigrid\node_modules\send\index.js:625:10)
    at onstat (D:\Node.js\zigrid\node_modules\send\index.js:737:10)
    at FSReqWrap.oncomplete (fs.js:123:15)

2 个答案:

答案 0 :(得分:2)

if (fileExtension === '.xcss') {
    const css = compiler.compile(absolutePath)
    res.setHeader('Content-Type', 'text/css')
    console.log('>>> BEFORE')
    res.send(css) // <----- The offending line.
    console.log('>>> AFTER')
 }

 next() //remove this line

我认为问题与您在发送http响应后调用next()这一事实有关。 next()调用链中的下一个中间件,如果由于任何原因您在send()之后编写响应流或标头,则会导致错误。

尝试避免在您输入if分支时调用next()或确保即将到来的中间件不设置任何标头

答案 1 :(得分:1)

if (fileExtension === '.xcss') {
    const css = compiler.compile(absolutePath)
    res.setHeader('Content-Type', 'text/css')
    console.log('>>> BEFORE')
    res.send(css) // <-----Removet this line and add next(css); 
    console.log('>>> AFTER')
 }