XMLHttpRequest でのリダイレクト処理

XMLHttpRequest でリダイレクトがうまく処理できなくて困ったので調べてみた。

結論

サーバのレスポンスがリダイレクト (30X) の場合、XMLHttpRequest が勝手にリダイレクトしてくれてリダイレクト先のレスポンスが返ってくる。
つまり、転送先が正しければ 200 が返ってくるし、存在しなければ 404 が返ってくるということ。
responseText の中身も転送先の内容になる。

ググってみたけど、探し方が悪いのかちょっと古めの記事しか見つからなかった。
XMLHttpRequestオブジェクトでRedirectをハンドリングするには?(リダイレクトを拾う方法) - on the center line.
ku

結局、上と同じようにレスポンスの内容によって転送と判断して window.location を書き換えて対応した。
XMLHttpRequest では、基本的に同一ドメインアクセスで転送先は分かるはずなのでこれでいいのかなあ。

試したこと

下記のファイルを使って確認してみた。
一応、同期/非同期通信のそれぞれの方式をChromeSafariFirefox 試したけど結果は全て同じ。

使ったファイルと処理の流れ

1. hoge.html から fuga.php へ GET リクエスト。
2. fuga.php が piyo.html へ転送
3. hoge.html のコンソールログに piyo.html のレスポンス表示

hoge.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8" />
  <title>test</title>
  <script>
    function sync() {
      var xhr = new XMLHttpRequest();
      xhr.open('GET', './fuga.php');
      xhr.send(null);
      console.log(xhr.status);
      console.log(xhr.getAllResponseHeaders());
      console.log(xhr.responseText);
    }
    function async() {
      var xhr = new XMLHttpRequest();
      xhr.onreadystatechange = function () {
        if (xhr.readyState==4){
          console.log(xhr.status);
          console.log(xhr.getAllResponseHeaders());
          console.log(xhr.responseText);
        }
      }
      xhr.open('GET', './fuga.php');
      xhr.send(null);
    }
  </script>
</head>
<body>
  <input type="button" value="sync" onClick="sync()">
  <input type="button" value="async" onClick="async()">
</body>
</html>
fuga.php
<?php
header("Location: ./piyo.html");
piyo.html
piyo.html
レスポンスヘッダ

Accept-Ranges bytes
Connection Keep-Alive
Content-Length 10
Content-Type text/html
Date Sat, 01 Mar 2014 14:03:43 GMT
Etag "5f49f6-a-4f38bc8295bc0"
Keep-Alive timeout=15, max=98
Last-Modified Sat, 01 Mar 2014 13:46:31 GMT
Server Apache/2.2.24 (Unix) DAV/2 PHP/5.5.8

レスポンスボディ

piyo.html