You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel 11+PHP8.2+TwillCMS中404 URL无法通过Web中间件求助

解决Laravel重定向中间件无法处理404请求的问题

问题根源

Laravel的路由中间件(比如你加入web组的中间件)只会在路由匹配成功后执行,而404请求分为两种场景:

  1. 路由完全未匹配:请求路径没有对应任何路由定义,此时路由中间件不会触发
  2. 模型绑定失败:比如show(Page $page)中Page不存在,Laravel会直接抛出ModelNotFoundException并进入异常处理流程,可能跳过你的重定向逻辑

解决方案

方案1:将重定向中间件设为全局中间件

全局中间件会对所有请求生效,无论路由是否匹配。修改bootstrap/app.php:

// 追加到全局中间件列表
$middleware->append(\App\Http\Middleware\Redirector::class);

然后在中间件中添加过滤逻辑,避免影响API等非web请求:

public function handle(Request $request, Closure $next)
{
    // 跳过API路由(根据你的实际路由规则调整)
    if ($request->is('api/*')) {
        return $next($request);
    }

    // 重定向逻辑:检查数据库中的重定向规则
    $redirect = \App\Models\Redirect::where('old_url', $request->path())->first();
    if ($redirect) {
        return redirect()->to($redirect->new_url, $redirect->status_code);
    }

    return $next($request);
}

方案2:通过异常处理器捕获404场景

如果不想用全局中间件,可在异常处理器中统一处理所有404情况。修改app/Exceptions/Handler.php:

use Illuminate\Database\Eloquent\ModelNotFoundException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

public function register()
{
    // 处理路由未匹配的404
    $this->renderable(function (NotFoundHttpException $e, $request) {
        $redirect = \App\Models\Redirect::where('old_url', $request->path())->first();
        if ($redirect) {
            return redirect()->to($redirect->new_url, $redirect->status_code);
        }
    });

    // 处理模型绑定失败的404(比如Page找不到)
    $this->renderable(function (ModelNotFoundException $e, $request) {
        $redirect = \App\Models\Redirect::where('old_url', $request->path())->first();
        if ($redirect) {
            return redirect()->to($redirect->new_url, $redirect->status_code);
        }
    });
}

方案3:修复Fallback路由的使用

如果坚持用Route::fallback(),确保以下几点:

  1. 将Fallback路由放在web.php的最后一行,保证它是最后匹配的路由
  2. 清除路由缓存(如果开启了缓存):php artisan route:clear
  3. 直接在Fallback闭包中加入重定向逻辑(或确保中间件已正确关联):
// web.php 最后一行
Route::fallback(function (Request $request) {
    // 先检查重定向
    $redirect = \App\Models\Redirect::where('old_url', $request->path())->first();
    if ($redirect) {
        return redirect()->to($redirect->new_url, $redirect->status_code);
    }
    // 无重定向则返回404视图
    return view("404");
});

方案4:自定义模型绑定逻辑

针对Page模型绑定失败的场景,可在RouteServiceProvider中自定义绑定逻辑:

public function boot()
{
    parent::boot();

    Route::bind('page', function ($value) {
        $page = \App\Models\Page::where('slug', $value)->first();
        
        if (!$page) {
            // 检查是否有对应重定向
            $redirect = \App\Models\Redirect::where('old_url', request()->path())->first();
            if ($redirect) {
                throw new \Illuminate\Http\Exceptions\HttpResponseException(
                    redirect()->to($redirect->new_url, $redirect->status_code)
                );
            }
            abort(404);
        }
        
        return $page;
    });
}

内容的提问来源于stack exchange,提问作者Exarillion

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 16:43:17