Turbolinks + HTTP Redirectの注意

「公式ドキュメントにちゃんと書いてある + 考えてみれば当たり前」なのだが、今日数分消費してしまったのでメモ。

TL; DR

  • Turbolinks-Location HTTPヘッダを出力しよう
    • turbolinks gemを使ってる場合は勝手にやってくれるよ
  • これがないと、RedirectしたときにブラウザのURL欄がリダイレクト先に変わってくれないよ

詳細

とは言っても、公式にちゃんと書いてある。

GitHub - turbolinks/turbolinks: Turbolinks makes navigating your web application faster

あえて解説する。

その前に、turbolinksの仕組みについてはこちらに書いてあるので見て欲しい。

nisshiee.hatenablog.jp

  • HistoryAPIを使って、まるでページ遷移したかのように見せる

ここでセットしているURLは、あくまでaタグのhref属性に記述されているURLなのだ。たとえこのリンク先がリダイレクトだった場合も。XHRはリダイレクトを追ってくれるので、ページの中身はちゃんとリダイレクト先の内容に書き換わるが、「HistoryにセットするURLがリダイレクトによって変化したこと」は検知できないというわけだ。

で、turbolinksはこれを次善の策で回避していて、「HTTPヘッダにURLを入れておいてくれれば、hrefの値ではなく、ヘッダの値を使うよ」と。HTTPヘッダはXHRで取得できるから、JSレイヤーがHistoryにセットすべき値を拾うことができる。

というわけで、ドキュメントにあるとおり、Turbolinks-Locationヘッダをセットしておくと、この問題は回避できる。

Rails

Railsを使っている場合は、そもそもturbolinksというgemを使っている場合がある。その場合は、実は勝手にこのヘッダを追加してくれるので、気にしなくて良い。

もしgemを使っていないなら、以下のようにヘッダ出力処理を追加してやる。

class ApplicationController < ActionController::Base
  before_action :set_turbolinks_header

  def set_turbolinks_header
    response.set_header('Turbolinks-Location', request.fullpath)
  end
end