web-dev-qa-db-ja.com

express.jsで、1つの関数でjsonとhtmlの両方へのリクエストをキャプチャする方法はありますか?

誰かが方法を知っていますか express.js htmlとjsonの両方の単一の関数でリクエストをキャプチャするには?

基本的に、両方に1つのルートが必要です/usersおよび/users.json --like Railsはそのルートで行います->コントローラー。

そうすれば、ロジックを1つの関数にカプセル化して、htmlまたはjsonのいずれかをレンダリングすることを決定できます。

何かのようなもの:

app.get('/users[.json]', function(req, res, next, json){
  if (json)
    res.send(JSON.stringfy(...));
  else
    res.render(...); //jade template
});

おそらくパラメータを使用できますか?

25
justinjmoses

ルートは、マニュアルに記載されているように、内部でRegExpにコンパイルされる単純な文字列であるため、次のようなことができます。

app.get("/users/:format?", function(req, res, next){
  if (req.params.format) { res.json(...); }
  else {
    res.render(...); //jade template
  }
});

詳細はこちらをご覧ください: http://expressjs.com/guide.html#routing

20
alessioalex

res.format() がExpress3.xおよび4.xでこれを行う方法だと思います。

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

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

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

これはAcceptヘッダーに依存していますが、カスタムミドルウェアなどを使用してこのヘッダーを自分で変更できます connect-acceptoverride

カスタムミドルウェアの一例は次のとおりです。

app.use(function (req, res, next) {
  var format = req.param('format');

  if (format) {
    req.headers.accept = 'application/' + format;
  }

  next();
});
54
Beau

私は上記の答えに満足していませんでした。これが私が代わりにしたことです。それがあなたを助けるならば、投票してください。

すべてのjsonリクエストでContent-Typeヘッダーが「application/json」に設定されていることを確認します。

if (req.header('Content-Type') == 'application/json') {
  return res.json({ users: users });
} else {
  return res.render('users-index', { users: users });
}
1
ajbraus