Conditional serving of web pages based on "Accept" header with express?

14,187

Solution 1

You're on the right track. Here's a nice example from Express about using req.accept:

app.use(function(req, res, next){
  res.status(404);

  // respond with html page
  if (req.accepts('html')) {
    res.render('404', { url: req.url });
    return;
  }

  // respond with json
  if (req.accepts('json')) {
    res.send({ error: 'Not found' });
    return;
  }

  // default to plain-text. send()
  res.type('txt').send('Not found');
});

Updated:

You can use res.send to send files without rendering:

res.set('Content-Type', 'text/html');
res.send(new Buffer(fs.readFile(__dirname + 'index.html'));

Solution 2

You can just use res.format to do the same thing. The example from the express docs:

res.format({
  text: function(){
    res.send('hey');
  },

  html: function(){
    res.send('<p>hey</p>');
  },

  json: function(){
    res.send({ message: 'hey' });
  }
});

You can read more about it here: http://expressjs.com/en/api.html#res.format

Share:
14,187
zero298
Author by

zero298

Game Programmer and Application Developer

Updated on July 22, 2022

Comments

  • zero298
    zero298 almost 2 years

    I understand that you can serve static content over express with:

    app.use(express.static(__dirname + "../../../public_html"));
    

    However, I'm trying to have express change the presentation of the content it delivers based upon the "Accept" header the the response sends over. Normally, the content that I have is requested in a JSON format through a REST API so the url is: http://blah.com/this/that/item and that works well.

    However, I would also like for users to be able to access that same page from a browser which would send over something like: Accept:text/html and because of that header, see a page with correct formatting (CSS/JS/HTML/etc) to present the same information.

    Right now, I'm trying to serve the content through:

    if (req.accepts("text/html")) {
       res.sendfile("/", {
          root: "../../../public_html"
       });
       res.status(200);
       return;
    }
    

    Where public_html holds index.html and the relative directories with the CSS and JS. I won't send that file whenever this is finished, but I figured it would be a good start and then add the JSON content after I figured out how to serve static content based on the Accept header.

    Is there a better way to do this?

  • zero298
    zero298 about 10 years
    This would require me to use a rendering engine though, correct? What about if I want to serve up a static html page instead? I may be incorrect, I only read about how res.render needs a render engine and then read about jade and that it needs a specific, separate markup.