【问题标题】:Express serving static file: can't set headers after they are send快递服务静态文件:发送后无法设置标题
【发布时间】:2017-06-23 15:53:16
【问题描述】:

我正在使用 express.static 内置中间件函数来提供静态文件,但控制台打印错误:Can't set headers after they are sent

这是我的代码,我不知道这有什么问题

'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

【问题讨论】:

    标签: node.js express


    【解决方案1】:

    要解决这个问题,您需要使用 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();
    });
    

    编辑:

    正如您在 cmets 中所说,上述方法不起作用,所以您可以使用 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 我编辑了帖子,请尝试我所说的并告诉这是否有任何不同
    猜你喜欢
    • 2015-02-23
    • 1970-01-01
    • 1970-01-01
    • 2017-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-27
    • 2011-01-23
    相关资源
    最近更新 更多