Conditional serving of web pages based on “Accept”

2020-06-16 05:31发布

问题:

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?

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


回答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