CORS のプリフライト・リクエストを観察する

1. このページの目的

CORS の preflightリクエストの動作を観察する。

2. 方法

Fetch API で外部ドメインにリクエストを送信するのであるば、preflight を発生させるために Content-Type: application/json フィールドをセットしたリクエストを送信する。

ブラウザの開発者ツールで、そのやり取りを観察する。

Chrome の DevTools を使う場合は、chrome://flags/#out-of-blink-cors というフラグを無効にしないと [Network]パネルに preflight リクエストが表示されないので注意。

サーバー側のコード(抜粋)

app.use(function(req, res, next) {
  // misc.laboradian.com からのアクセスを許可します
  res.header("Access-Control-Allow-Origin", "https://misc.laboradian.com");
  // Content-Type フィールドを許可します
  res.header("Access-Control-Allow-Headers", "Content-Type");
  next();
});

app.get("/cors-preflight-test.json", function(request, response) {
  // JSONファイルを返します
  response.sendFile(__dirname + "/views/cors-preflight-test.json");
});

クライアント側のコード(抜粋)

document.querySelector('#btn1').addEventListener('click', function() {

  const myHeaders = new Headers();
  // Content-Type に application/json をセットします
  myHeaders.append('Content-Type', 'application/json');

  const myInit = {
    method: 'GET',
    headers: myHeaders,
    mode: 'cors',
    cache: 'default'
  };

  fetch('https://bramble-cors-test.glitch.me/cors-preflight-test.json', myInit)
    .then(function(response) {
      if(response.ok) {
        console.log('response OK');
        return response.json();
      } else {
        console.log('response NOT OK');
        throw new Error('Network response was not ok.');
      }
    })
    .then(function(myJson) {
      console.log(JSON.stringify(myJson));
    })
    .catch(function(error) {
      console.log('There has been a problem with your fetch operation: ', error.message);
    })
  ;

});

参考

3. 実験

以下のボタンを押すと、外部ドメインのURLに対して Fetch API によってリクエストを投げる。

(1) preflight を発生させるリクエスト

(2) preflight を発生させないリクエスト

4. 結果

(1) のボタンを押すことで、想定通りに観察できた。

Chrome 80.0.3987.100 (Official Build) (64bit)

OPTIONリクエストの後、GETリクエストを送信している
preflight その1
preflight その2

Firefox 73.0 (64bit)

Firefox での結果

5. 参考