node.js - 快速提供静态文件: can't set headers after they are send

标签 node.js express

我正在使用express.static内置中间件函数来提供静态文件,但是控制台会打印错误:发送后无法设置 header 。

这是我的代码,我不知道这是怎么了

'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);

当我请求2个现有的jpg文件时,我在一个jpg文件中也收到404错误
404 screenshot

最佳答案

为了解决这个问题,您需要使用app.use函数而不是app.all来安装中间件函数。 app.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方法在提供文件之前设置 header ,如下所示:
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之上,这样就不会调用用于设置 header 的app.use方法,因此不会再次设置 header 。

关于node.js - 快速提供静态文件: can't set headers after they are send,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44725541/

相关文章:

javascript - 使用 node.js 将 div 的类更改为不同的 CSS 类

css - NodeJS (EJS) 添加样式表 - 未找到

node.js - 如何在 node.js 中设置 View (模板)目录和静态文件的路径

javascript - 快速 js session 中的未定义错误

node.js - 如何保护我的 REST-API?

Node.js Sequelize 无法读取 nulll 的属性

php - Node.js 中的 PHP exit()/die() 等价物是什么

node.js - 使用 socket.io、node.js 和 mongodb 更新服务器端的 ejs 变量

node.js - 如何在 Nodejs 中使用监听器的回调函数而无需内联编写?

node.js - 打破 Nunjucks 循环