Express提供静态文件服务:无法在发送后设置头信息。

6
我正在使用内置的express.static中间件函数来提供静态文件,但控制台打印错误:在发送响应后不能设置响应头
以下是我的代码,我不知道哪里出了问题。
'use strict';

let path = require('path');
let express = require('express');
let bodyParser = require('body-parser');
let mongoose = require('mongoose');
let formidable = require('express-formidable');
let routes = require('./routes');
let app = express();
let port = process.env.PORT || 3000;


let db = mongoose.connect('mongodb://localhost:27017/old-driver');

// deal with img post
app.use(formidable({
  uploadDir: path.join(__dirname, 'upload'),
  keepExtensions: true
}));

app.use(bodyParser.urlencoded({extended: true })); 
app.use(bodyParser.json());

// access-control
app.all('*', (req, res, next) => {
  res.set("Access-Control-Allow-Origin", "*");
  res.set("Access-Control-Allow-Headers", "Content-Type,X-Requested-With");
  res.set("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
  res.set("X-Powered-By",' 3.2.1')
  res.type("application/json");
  res.type("jpg");
  next();
});


// set assets path, GET /assets/demo.png
app.use('/assets', express.static('upload'));

routes(app);

app.listen(port);

路由中间件方法:
getAllTeachers: (req, res) => {
    Teacher.find({}, (err, teacher) => {
        if (err) {
            res.send(err);
        } else {
            res.json(teacher);
        }
    });
},

即使我删除了下面显示的访问控制代码,仍然会出现错误。
let db = mongoose.connect('mongodb://localhost:27017/old-driver');

// deal with img post
app.use(formidable({
  uploadDir: path.join(__dirname, 'upload'),
  keepExtensions: true
}));

app.use(bodyParser.urlencoded({extended: true })); 
app.use(bodyParser.json());

// set assets path, GET /assets/demo.png
app.use('/assets', express.static('upload'));

routes(app);

app.listen(port);

当我请求两个现有的jpg文件时,其中一个jpg文件出现404错误。 404截图
1个回答

17

要解决这个问题,你需要使用 app.use 函数来挂载中间件函数,而不是使用 app.allapp.use 将中间件函数添加到中间件栈中,确保它们按照添加的顺序执行。

因此你需要这样做:

app.use((req, res, next) => { //change app.all to app.use here and remove '*', i.e. the first parameter part
  res.set("Access-Control-Allow-Origin", "*");
  res.set("Access-Control-Allow-Headers", "Content-Type,X-Requested-With");
  res.set("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
  res.set("X-Powered-By",' 3.2.1')
  res.type("application/json");
  res.type("jpg");
  next();
});

编辑:

如您在评论中所说,上述方法不起作用,您可以使用express.static方法中的setHeaders方法,在文件被提供之前设置标头,例如:

app.use('/assets', express.static('upload', {
  setHeaders: function(res, path) {
    res.set("Access-Control-Allow-Origin", "*");
    res.set("Access-Control-Allow-Headers", "Content-Type,X-Requested-With");
    res.set("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
    res.set("X-Powered-By",' 3.2.1')
    res.type("application/json");
    res.type("jpg");
  }
}));

将这个静态文件服务中间件方法放在app.use之上,这样设置头文件的app.use方法就不会被调用,因此头文件也不会再次设置。


@Rcrab,我编辑了这篇文章,请尝试我的建议并告诉我是否有所改善。 - Zeus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接