Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Express serving static file: can't set headers after they are send

I am using the express.static built-in middleware function to serve static files, but the console prints the error: Can't set headers after they are sent.

here is my code, i don't know what is wrong with this

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

the route middleware method:

getAllTeachers: (req, res) => {
    Teacher.find({}, (err, teacher) => {
        if (err) {
            res.send(err);
        } else {
            res.json(teacher);
        }
    });
},

Even if I remove the access-contol code as shown below, still get error

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

when I request 2 existing jpg file, I also get 404 error in one jpg file 404 screenshot

like image 973
Rcrab Avatar asked Dec 14 '22 22:12

Rcrab


1 Answers

To solve this you need to use app.use function instead of app.all for mounting your middleware function. app.use adds the middleware function to middleware stack ensuring that they are executed in same order at which they are added.

So you need to do this :

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();
});

EDIT:

As you told in comments the above method doesn't work so what you can do is use the setHeaders method of express.static method to set headers before file is served like this :

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");
  }
}));

Put this static file serving middleware method above the app.use so that app.use method for setting headers is not called hence the headers won't be set again.

like image 111
Zeus Avatar answered Dec 21 '22 11:12

Zeus