はじめに
戻るボタンを実装するケースは多くあると思いまして、忘備録がてら3つの実装方法をまとめました
Railsでフルスタック開発する方向けです
実行環境
- Ruby 4.0.2
- Rails 8.1.3
特定のページに戻りたい場合
<%= link_to "戻る", root_path %>
ルートパスへのリンクを生成します
これは当たり前ですかね
ただ、「戻る」と表示していながら遷移先URLはルート固定となっている為
ユーザーの意図とは違うページへ遷移する可能性もあります
これだと「戻る」ではなく「一覧へ」とかに文言を変更した方が良いかもしれません
前に表示していたページに戻りたい(外部サイト含む)場合
<%= link_to '戻る', 'javascript:history.back()' %>
ググるとよく紹介されてるやつ
JavaScriptのhistory.back()を使用することでブラウザの履歴の1つ前のページへ戻ることが出来ます
実装も楽で直感的な動作を実現することが出来ます
デメリットとしてはJavaScript依存である為、ブラウザのJavaScriptを無効化されると動作しなくなります
また外部(SNS等)からアクセスした際、戻るボタンをクリックすると外部のページへ戻ることとなります
これは意図した動作にはなるかもしれませんが、アプリケーションから離脱されることになります
前に表示していたページに戻りたい(外部サイト含まない)場合
<%= link_to "戻る", url_from(request.referer) || root_path %>
前述した2つより少し複雑ですね
大まかな挙動としてrequest.refererのURLがアプリと同一ドメインの場合はURLを返し、それ以外はroot_pathを返す、という感じです
外部から直接アクセスされて戻るボタンをクリックした場合も、アプリケーション内へ遷移させることが出来ます(request.referer == nil と判定される為)
1つずつ分解して解説していきます
url_from()
railsが標準で用意しているメソッドです
引数のURLが同一ドメイン(example.com の部分)の場合はそのままURLを返す、異なる場合はnilを返す。という挙動です
# request.host is example.com:
url_from("https://example.com/profile") # => "https://example.com/profile"
url_from("http://example.com/profile") # => "http://example.com/profile"
url_from("http://evil.com/profile") # => nil
本来はcontrollerで使用されることを想定している為、viewで使えるようにする為に事前に読み込んでおく必要があります
# app/controllers/application_controller.rb
helper_method :url_from
request.referer
直前にいたページのURLを返します
仕組みとしてはHTTPヘッダの Referer を参照してURLを返します
開発者ツールからも見ることが出来ます(※筆者はChromeで実行しています)
以下の手順で見ることが出来ます
開発者ツール→
Network→1番上のファイル→Headers→Request Headers →Referer
今回はgoogle.comでQiitaを検索しアクセスした為、google.com の記載があります
|| root_path
左辺が false である場合に返されます
ここはRubyの基礎的な部分で本記事のスコープ外であるのでこれ以上の説明は省略します
最後に
いかがだったでしょうか
個人的には2つ目のhistory.back()をとりあえず使っておけば良いのかと思います
個人的な学びとして、
3つ目のurl_from()に関しては直接request.refererを埋め込まないことで オープンリダイレクト攻撃 を防いでいる。ということがありました
脱線しますがセキュリティ周りは一通り学んでおきたいです
参考文献
