AjaxとBrowser Cookie

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

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