7.

Laravel リダイレクト完全ガイド

編集
この記事の要点
  • Laravel のリダイレクトは redirect() ヘルパーで返す: return redirect('/')
  • 名前付きルート: redirect()->route('home') / 直前ページ: redirect()->back()
  • ログイン後の意図された URL に戻す: redirect()->intended('/dashboard')
  • フラッシュメッセージ: ->with('flash', '保存しました')、エラー: ->withErrors($validator)、入力保持: ->withInput()
  • 外部 URL は redirect()->away('https://...')、Blade からは <meta http-equiv="refresh"> や JS の window.location

基本: コントローラから redirect() を返す

Laravel のリダイレクトは「ビューを返す」のではなく「コントローラから RedirectResponse を返す」形が基本です。Blade ファイル内で直接リダイレクトはできません(HTML 出力に <meta refresh> や JS を書く形になります)。

public function store(Request $request)
{
    // ... 保存処理 ...

    // 1. パス直指定
    return redirect('/home');

    // 2. 名前付きルート
    return redirect()->route('home');
    return redirect()->route('user.show', ['id' => 1]);

    // 3. 直前のページに戻る
    return redirect()->back();
    return back();   // ヘルパー関数

    // 4. アクション指定
    return redirect()->action([HomeController::class, 'index']);
}

リダイレクトメソッド一覧

メソッド用途
redirect('/path')URL 直指定
redirect()->route('name', $params)名前付きルート(推奨)
redirect()->back() / back()直前のページに戻る
redirect()->intended('/default')認証ミドルウェアが保存した URL に戻る
redirect()->action([Ctrl::class, 'method'])コントローラアクション指定
redirect()->away('https://external')外部 URL(バリデーション通る)
redirect()->guest($url)未認証時のリダイレクト先記録用
redirect()->refresh()同じ URL に再リクエスト

フラッシュメッセージ・エラー・入力の保持

// フラッシュメッセージ(次のリクエストでのみ参照可能)
return redirect()->route('home')
    ->with('success', '保存しました');

// 複数
return redirect('/')->with([
    'status' => 'ok',
    'message' => '更新完了',
]);

// バリデーションエラー
return redirect()->back()
    ->withErrors($validator)
    ->withInput();          // 入力値を flash して old() で復元

// withInput で特定キーのみ
return back()->withInput($request->only(['email']));

// withInput で特定キー除外
return back()->withInput($request->except(['password']));

// withCookie
return redirect('/')->withCookie(cookie('name', 'value', 60));

Blade 側で受け取る:

{{-- フラッシュメッセージ --}}
@if (session('success'))
    <div class="alert alert-success">{{ session('success') }}</div>
@endif

{{-- バリデーションエラー --}}
@error('email')
    <span class="text-red-500">{{ $message }}</span>
@enderror

{{-- 直前の入力値を復元 --}}
<input name="email" value="{{ old('email') }}">

ログイン後の元のページに戻す: intended()

auth ミドルウェアは未認証ユーザを /login に飛ばすときに、「本来行きたかった URL」をセッションに記録します。ログイン処理後に intended() で読み出します。

public function login(Request $request)
{
    if (Auth::attempt($request->only('email', 'password'))) {
        $request->session()->regenerate();

        // セッションに保存された intended URL があればそこへ
        // なければ '/dashboard'
        return redirect()->intended('/dashboard');
    }

    return back()->withErrors(['email' => '認証失敗']);
}

HTTP ステータスコードの指定

SEO 観点でリダイレクトの種別は重要です。Laravel デフォルトは 302 (Found)。永続的な移転は 301 (Moved Permanently) を明示します。

// 301 永続的リダイレクト
return redirect('/new-path', 301);
return redirect()->route('new.home', [], 301);

// 308 (Permanent Redirect, メソッド保持)
return redirect('/api/v2', 308);

// 303 (See Other, POST → GET 変換)
return redirect('/result', 303);

// レスポンスを後から書き換える
return redirect('/')->setStatusCode(301);
コード意味用途
301Moved Permanently恒久的な URL 変更(SEO 反映)
302Found一時的(Laravel デフォルト)
303See OtherPOST 後の GET 遷移(PRG パターン)
307Temporary Redirect一時的、メソッド保持
308Permanent Redirect恒久、メソッド保持

外部 URL へのリダイレクト

redirect() はオープンリダイレクト対策で外部 URL に飛ばすと例外が出る場合があります。明示的に外部に飛ばすなら away():

return redirect()->away('https://example.com/external');

// ❌ オープンリダイレクト脆弱性に注意
return redirect()->away($request->input('next'));  // 危険

// ✅ ホワイトリスト検証してから away
$next = $request->input('next');
$allowed = ['example.com', 'partner.example.com'];
if (in_array(parse_url($next, PHP_URL_HOST), $allowed)) {
    return redirect()->away($next);
}
abort(400);

Blade / フロント側からのリダイレクト

「ビュー内でリダイレクト」は本来コントローラ側でやるべきですが、どうしても HTML 描画後に飛ばしたい場合:

{{-- meta refresh(3秒後にリダイレクト) --}}
<meta http-equiv="refresh" content="3;URL='/destination'">

{{-- JavaScript --}}
<script>
  // 履歴に残す
  window.location.href = "{{ route('home') }}";

  // 履歴に残さない(戻るボタンで戻れない)
  window.location.replace("{{ route('home') }}");

  // 遅延
  setTimeout(() => location.href = '/', 2000);
</script>

Ajax / API リクエスト時の注意

Ajax / SPA から POST した場合、サーバが 302 を返してもブラウザは「Ajax レスポンス」として受け取るだけで自動遷移しません。フロント側で response.headers.get('Location') を見るか、JSON で URL を返すパターンが推奨です:

if ($request->wantsJson()) {
    return response()->json([
        'redirect' => route('home'),
        'message' => '保存しました',
    ]);
}

return redirect()->route('home')->with('success', '保存しました');

FAQ

Q: redirect()->back() がトップに飛ぶ
A: 直前ページがセッション/Referer から取れない場合の挙動です。back(fallback: route('home')) でフォールバックを指定できます。

Q: 301 にすると以前のリダイレクト先がブラウザにキャッシュされて変更できない
A: ブラウザは 301 を強くキャッシュします。検証中は 302 を使い、本番リリース時のみ 301 に切り替えるのが安全。デバッグ時はシークレットウィンドウや DevTools の Disable Cache で。

Q: フラッシュメッセージが session() から取れない
A: web ミドルウェアグループに属しているか確認。routes/api.php はステートレスでセッションが無効なため with() は機能しません。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. クラスベースビュー(主流)の作り方とviewの分割
  2. 関数ベースビューの作り方とviewの分割
  3. URLディスパッチャー(ルーティング処理)
  4. GETとPOSTパラメータ受け取り
  5. クラスベースビューでGET/POSTリクエストの受け取り方
  6. クラスベースビューでテンプレートに値を渡す方法
  7. ビューでリダイレクト
  8. cookieの値の設定と取得
  9. HTTPステータスコードの返し方

最近更新/作成されたページ