4からはデフォルトで使用されるようになります。3までの書き方をしているとまず間違いなく問題が起きます。4ではデフォルトの機能ですので、最新版を使いたいなら必ず知っておかなければいけません。本エントリではturbolinksを使うために絶対に知らなければいけないことを分かりやすく紹介したいと思います。動作turbolinksの動作は、すごく大雑把に言うと以下の通りです。現在のページと取り寄せたページの外部JavaScriptファイルとCSSファイルが同一なら、titleとbodyを読み込んだページのもので置き換える実際に上の動作になるのはGETの場合だけで、無効になる条件や方法もあります(後述)。前のページの内容は最大10ページ分キャッシュに保存されます。イベントturbolinksでページをロードすると、jQueryのreadyイベントが発火しません。$(function(){})に入ってる処理が実行されないということです。代わりに以下の4つのイベントが用意されています。何らかの方法でページが更新されたXHRが使われた場合、イベントの順序はpage:fetchpage:changepage:loadキャッシュから復元された場合はpage:changepage:restoreとなります。イベントのtargetはdocumentです。ある問題readyが発火しない前述の通り、まずreadyイベントハンドラが呼ばれないという問題が起きます。readyとpage:loadを使い分けるのが正しい対処ですが、page:loadのタイミングでreadyイベントハンドラを実行してくれるjquery.turbolinksというgemもあります。jquery.turbolinksを導入すればturbolinks対応完了かというと、そうは行かず、jquery.turbolinksのREADME.mdにも書かれている通り、documentに登録したイベントハンドラが複数回実行されるようになることがあります。これは例えば、以下のようなコードを書いている場合に発生します。myHandler);});上のコードでは、readyイベントでdocumentにイベントハンドラを登録しています。ところがturbolinksによってページが更新された場合、jquery.turbolinksによってreadyイベントハンドラは実行されますがdocumentオブジェクトは前のページから引き継がれるため、同じdocumentオブジェクトに2つ目のイベントハンドラが登録されてしまいます。これを避けるには、以下のようにdocumentへのイベントハンドラ登録を$(function(){})の外でやるようにします。myHandler);windowのloadイベントが発火しない前述のreadyイベントはページ中の全てのDOMが参照可能になったときに発火しますが、windowのloadイベントはページ中の全ての要素をロードし終わった時に発火します。JavaScriptコードの中で画像のサイズを使用する場合など、loadイベントが必要になることがありますよね。ところがturbolinksでページが更新されたときはwindowのloadイベントハンドラも実行されません。この問題を回避する最も簡単な方法は、当該ページへの遷移時にturbolinksを無効にすることです。turbolinksを無効にするには、リンクかその先祖要素にdata-no-turbolink属性を付けます。以下のように書いてあると、/fooへ遷移するときturbolinksは動作しません。data-no-turbolink="1">foo</a>metaタグが更新されないturbolinksが更新してくれるのはtitleとbodyだけですので、head内にあるmetaは対象外です。これは例えば、GETでログアウトできるようなサイトで問題になります。問題発生のシナリオは以下の通りです。ユーザがログインフォームを開き、csrf-tokenの入ったmetaタグが表示されるログインするGETでログアウトする。session中のcsrf-tokenは更新されるが、metaタグは更新されない再びログインフォームを開く。ujsによってmetaタグのcsrf-tokenがフォームにコピーされるsessionとフォームのcsrf-tokenが異なるためInvalidAuthenticityTokenが発生この問題はログアウトをDELETEで行なっていれば発生しませんが、GETのログアウトが必要な事情もあるでしょう。このような場合には、bodyの中にmetaを更新するスクリプトを書くことで回避できます。行儀の良いやり方とは言えないでしょう。requestもありますが、DHHは「これが不可欠なユースケースを聞いたことがない」と一蹴しています。まとめturbolinksを使う際には以下のことに注意する必要があります。GETでページ遷移したとき:jQueryのreadyイベントは起きないwindowのloadイベントも起きないmetaタグが更新されない面倒かもしれませんがウェブアプリの進化は待ってくれません。いつ使うか?今でしょ!(追記)turbolinksに関するセキュリティ上の懸念についてturbolinksを採用しているサイトでは、条件次第で攻撃者が任意のJavaScriptを実行させられます(いわゆるXSS)。攻撃が成立するパターンには以下の2つがあります。パターン1:自動リンクとアップロード条件ユーザが投稿したテキストにURLが入っていると自動的にリンクになって表示されることファイルをアップロードでき、同じサイトのURLが付与されてダウンロード可能になること攻撃成立の流れは以下の通りです。攻撃用スクリプトを含んだHTMLファイルを、拡張子を偽ってアップロードする。攻撃用ファイルはURLが付けられ、ダウンロード可能になる。攻撃用ファイルはturbolinksが効くようにheadの中身を書く攻撃用ファイルのURLを投稿する。このときファイル名の後に「#foo.html」などを加え、リンクの最後をhtmlにする。自動的にリンクとなって表示される被害者がリンクを辿る。attachmentで配信されるようにします。2条件ユーザが投稿したテキストにURLが入っていると自動的にリンクになって表示されること(パターン1と同じ)パラメータとしてURLを渡すとそこへリダイレクトする機能がサイト内にあることXHRで外部サイトへリダイレクトするブラウザ(IE10など)を被害者が使っていることこちらは以下のような流れで攻撃が成立します。攻撃者は攻撃用スクリプトを含んだページを自分のサイトに置く。攻撃用ページのheadはturbolinksが効くように書く攻撃先サイトのオープンリダイレクタを通して攻撃用ページへ行くURLを投稿する。自動的にリンクとなって表示される被害者がリンクを辿る。turbolinksが攻撃用ページをリダイレクトで取得し、中のスクリプトを実行するこちらも自動リンクにdata-no-turbolinkを付けることが対策になります。実際に攻撃する為に必要な事(追記ここまで)宣伝DocBaseとは小さく始める・みんなで育てる・適切に伝える・安心して伝えるをコンセプトにした情報共有サービスです。メモという形で小さく始められる、エンジニア以外のメンバーでも使いやすい仕組み、情報をまとめて整理できる、柔軟な権限設定で様々なプロジェクトで使えるなど、積極的な情報共有と業務の効率化を実現し、チームの成長を促します。date*日本語が含まれない投稿は無視されますのでご注意ください。fax.0422-26-9781お問い合わせはこちらからどうぞ。