History APIとbase要素

base要素のhref要素で別のドメインのページを指し、リソースの基準となるURLを変更すると、History APIを使った履歴操作が行えなくなる。Same Origin Policyに引っかかって、セキュリティ・エラーが吐かれるようだ。

<!-- http://www.example.com/foo/bar -->
<base href="http://other.example.com/">
<script>
  history.replaceState(null, '', '/replace');
</script>

http://www.example.com/上のページでURLの書き換えを行おうと以上のようにすると、ブラウザーはbase要素のhref属性の値を考慮してhttp://other.exmaple.com/replaceに書き換えようとする。しかしSame Origin Policyが発動して例外を吐いてスクリプトの実行が止まる。Chrome 34ではコンソールに以下のようなエラーが表示される。

Uncaught SecurityError: Failed to execute 'replaceState' on 'History': A history state object with URL 'http://other.example.com/push' cannot be created in a document with origin 'http://www.example.com/'.

base要素で別のドメインを使いつつ履歴操作……というのは不可能なようだ。

ちゃっちゃと作ったHTML生成ツールでローカルでのパスのミスマッチなどを考慮しなくて済むようにbase要素を常に使うような実装にしたんだけど、そのままだとどうにもならなそう。履歴書き換え前に一旦base要素を削除するとかでもいけそうな気がしないでもないけど、それもちょっとアレな感じする。