基于“Accept”头在Express中有条件地提供Web页面?

11

我明白你可以使用以下方式在Express中提供静态内容:

app.use(express.static(__dirname + "../../../public_html"));
然而,我正在尝试让Express根据响应发送的"Accept"标头来更改其传递内容的呈现方式。通常,我有的内容是通过REST API以JSON格式请求的,因此URL为:http://blah.com/this/that/item,这很有效。
然而,我还希望用户能够从浏览器访问同一页,浏览器会发送类似于Accept:text/html的东西,由于该标头,用户可以看到具有正确格式(CSS/JS/HTML等)的页面,以呈现相同的信息。
目前,我正试图通过以下方式提供内容:
if (req.accepts("text/html")) {
   res.sendfile("/", {
      root: "../../../public_html"
   });
   res.status(200);
   return;
}

public_html 文件夹中包含 index.html 和相对应的文件夹(包含 CSS 和 JS)。完成后,我不会发送该文件,但我认为这是一个好的起点,然后在弄清楚如何根据“Accept”标头提供静态内容后再添加 JSON 内容。

有更好的方法吗?

2个回答

18

你走在正确的道路上。这里有一个来自Express的漂亮 示例,关于如何使用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');
});

更新:

您可以使用 res.send 方法发送文件而无需进行渲染:

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

这需要我使用渲染引擎,对吗?如果我想提供一个静态的HTML页面呢?我可能是错误的,我只是读到了res.render需要一个渲染引擎,然后读到了jade,它需要一个特定的、单独的标记。 - zero298

16
您可以使用res.format来完成同样的事情。以下是来自 Express 文档的示例:
res.format({
  text: function(){
    res.send('hey');
  },

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

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

你可以在这里阅读更多信息:http://expressjs.com/en/api.html#res.format


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接