LoginSignup
4
4

More than 5 years have passed since last update.

expressのreq.format()を、urlの拡張子で判別してくれるようにする

Posted at

expressのres.format()メソッドを使うと、railsのrespond_toみたいに、レスポンスのContent-Typeごとに実行する処理を分けることがきる。
(コンテントネゴシエーターとか呼ばれる機能らしい。)

  app.get('/hoge.:format', function(req, res) {
    res.format({
      json: function(req, res) {
        res.send({a: 1});
      },
      html: function(req, res) {
        // ブラウザから /index.json にアクセスしてもこっちが実行される
        res.render('index');
      },
      default: function(req, res) {
        res.send(406);
      }
    });
  });

上記のように書けば良いのだけど、このタイプの判定は、リクエストのAcceptヘッダを元に判定しているらしく、ヘッダがついていないと、たとえURLが /hoge.json だったとしても、jsonの処理が実行されない。

良いやりかたかどうかさだかではないけど、下記の容量で、expressのレスポンスタイプ判定メソッドを拡張すると、:formatという名前のパラメーターがついていた場合は考慮されるようになる。

  var __accepts = express.request.accepts;
  express.request.accepts = function(type) {
    var format = this.params.format
      , i;

    if (util.isArray(type)) {
      for (i = 0; i < type.length; i++) {
        t = type[i];
        if (type[i] === format) {
          return type[i];
        }
      }
    } else if (type === this.params.format) {
      return type;
    }
    return __accepts.call(this, type);
  };

  var __is = express.request.is;
  express.request.is = function(type) {
    return this.params.format === type || __is.call(this, type);
  };

app.param() とかの便利機能もあるけど、ヘッダを書き換えずにやるにはこういう方法しか思いつかなかった。

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4