AjaxとBrowser Cookie

「ブラウザからアクセスするのと、AjaxからアクセスするのってCookieってかわっちゃうの?」という質問をされたので自分なりの答えを書いていく。

Ajaxなのだが、JavaScriptで一番有名なlibraryのaxios/axiosを用いて書く。

FetchAPIについては今回は含めない。


結論

基本的にはCookieは変わらない。

同一オリジンの場合は自動的にCookieが使われる。

別オリジンの場合にCookieを使いたいなら { withCredentials: true } をoptionに持たせれば良い。

axios.get('https://www.uuum.jp', { withCredentials: true });

そもそもAjaxとはなんだろうか?

MDNにこう書いてある。

AJAX は Asynchronous JavaScript And XML の頭文字を取ったものです。 これは一言で言えば、 XMLHttpRequest オブジェクトを使ってサーバーと通信することです。 AJAX は JSON, XML, HTML, テキストファイルなど、様々な形式の情報で送受信することができます。 AJAX の最も魅力的な特徴は「非同期」であること、つまり、サーバーとの通信、データの交換、ページの更新を、ページの再読み込みなしに行うことができる点です。

要するに、JavaScriptから通信ができるというだけ。

XMLHttRequest のサンプルは以下。

const xhr = new XMLHttpRequest();
xhr.open("GET", "https://www.uuum.jp");
xhr.send();

console.log(xhr.status); // 200

これで通信ができる。以上だ。


axiosのコードを読んでみる。

axios/lib/adapters/xhr.jsXMLHttpRequest が書いてある。

var request = new XMLHttpRequest();

XMLHttpRequest を使っているのが確認できた。

さて、Cookieの扱い方はどうなっているだろうか? ググったら withCredentials を使えって書いてある。

実際にコード読んでみるとこんな記述がある。

axios/lib/adapters/xhr.js#L103-L105:

var xsrfValue = (config.withCredentials || isURLSameOrigin(config.url)) && config.xsrfCookieName ?
    cookies.read(config.xsrfCookieName) :
    undefined;

同一オリジンの場合や withCredentials の場合に cookies.read が走る。

Cookiesの定義元を読んで見る。

axios/lib/helpers/cookies.js:

(function standardBrowserEnv() {
  return {
    write: function write(name, value, expires, path, domain, secure) {
      var cookie = [];
      cookie.push(name + '=' + encodeURIComponent(value));

      if (utils.isNumber(expires)) {
        cookie.push('expires=' + new Date(expires).toGMTString());
      }

      if (utils.isString(path)) {
        cookie.push('path=' + path);
      }

      if (utils.isString(domain)) {
        cookie.push('domain=' + domain);
      }

      if (secure === true) {
        cookie.push('secure');
      }

      document.cookie = cookie.join('; ');
    },

    read: function read(name) {
      var match = document.cookie.match(new RegExp('(^|;\\s*)(' + name + ')=([^;]*)'));
      return (match ? decodeURIComponent(match[3]) : null);
    },

    remove: function remove(name) {
      this.write(name, '', Date.now() - 86400000);
    }
  };
})() :

document.cookie から取得してきている。 document.cookie のMDNはこれだ。

https://developer.mozilla.org/ja/docs/Web/API/Document/cookie