綺麗に死ぬITエンジニア

Node.js + ExpressへのOPTIONSメソッドの実装

2015-09-01

REST APIにアクセスする際に、ブラウザがAPIサーバに対してHTTP(もしくはHTTPS)のOPTIONSメソッドでリクエストを投げることがあります。

本記事では、その現象の解説と、Node.jsでAPIサーバを実装している場合のOPTIONSメソッドへの対応法を記述します。

HTTPのOPTIONSメソッドとは

HTTPで一般に使われるメソッドといえば、GETやPOSTですね。REST APIを頻繁に利用する人ならば、PUTやDELETEも利用したことがあるでしょう。サーバのテストのためにHEADメソッドを利用したことがある人もいるかもしれません。

OPTIONSメソッドは、これらのメソッドのうち、サーバがどのメソッドをサポートしているかを調査するためのメソッドです。

昨今のブラウザでは、フロントエンドJavaScriptから違うドメインへのアクセスに対して、Cross-Origin Resource Sharing(以下、CORSといいます)がサーバ側で許可されている場合を除き、セキュリティ上の問題からアクセスをしない仕様となっています。

そして、ブラウザはCORSを検出した場合、実際のメソッドを投げる前に、OPTIONSメソッドによる検査を実行するような仕様になっています。

つまり、APIサーバの実装には、

  • Cross-Origin Resource Sharingを有効にする(HTTPレスポンスヘッダにAccess-Control-Allow-Origin等の実装)
  • OPTIONSメソッドの実装

の2つが必須ということになります。

案外、この点を説明している資料が少ないように感じますね。

実際のコード

では、実際に実装する方法を以下に記述します。

var express = require('express');
var app = express();

/**
 \* Cross-Origin Resource Sharingを有効にする記述(HTTPレスポンスヘッダの追加)
 \*/
app.use(function (req, res, next) {
  res.header('Access-Control-Allow-Origin', req.headers.origin);
  res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept');
  res.header('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS');
  res.header('Access-Control-Allow-Credentials', true);
  res.header('Access-Control-Max-Age', '86400');
  next();
});

/**
 \* OPTIONSメソッドの実装
 \*/
app.options('*', function (req, res) {
  res.sendStatus(200);
});

/**
 \* あとは処理を記述していく
 \*/

app.get('/', function (req, res) {
  // 処理
});

app.listen(3000);

以上で終了です。Express、簡単ですね。

なお、OPTIONSメソッドの実装の部分で、

app.options('*', function (req, res) {
  res.send(200);
});

と記述している資料がネット上にいくらかありましたが、こうすると以下のエラーがNode.jsで出力されることがあります。

express deprecated res.send(status): Use res.sendStatus(status) instead app.js:20:7

記述にあるとおり、sendメソッドではなく、sendStatusメソッドを利用しましょう。

まとめ

Node.jsたのしい。