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

Laravel 8及以上版本中传递请求至异常处理并捕获404请求源URL的最佳实现方案

Laravel 8及以上版本中传递请求至异常处理并捕获404请求源URL的最佳实现方案

嘿,这个需求我刚好处理过好多次,Laravel 8及以上版本里其实有非常简洁的实现方式,完全不用复杂的配置就能搞定——因为Laravel的异常处理流程天生就能访问当前请求,你根本不需要手动“传递”请求到异常里,直接拿就行!

1. 核心实现:在异常处理器中捕获404请求信息

首先打开项目根目录下的app/Exceptions/Handler.php,我们要在report方法里针对404异常做专门处理。这个方法负责记录异常日志,刚好适合我们收集请求URL、用户代理(用来判断是不是机器人)、IP这些关键信息。

修改后的report方法示例:

public function report(Throwable $exception)
{
    // 专门捕获404异常
    if ($exception instanceof \Symfony\Component\HttpKernel\Exception\NotFoundHttpException) {
        // 获取请求的完整URL(包含查询参数)
        $requestUrl = request()->fullUrl();
        // 获取用户代理,用来识别爬虫/机器人
        $userAgent = request()->header('User-Agent');
        // 获取请求IP
        $ipAddress = request()->ip();

        // 方式一:单独记录一条清晰的404日志
        logger()->error('404 页面访问记录', [
            '访问URL' => $requestUrl,
            '用户代理' => $userAgent,
            '访问IP' => $ipAddress,
            '时间' => now()->toDateTimeString()
        ]);

        // 方式二:把信息附加到默认的异常日志上下文里
        parent::report($exception->withContext([
            'request_url' => $requestUrl,
            'user_agent' => $userAgent,
            'ip' => $ipAddress
        ]));
        return;
    }

    // 其他异常按默认逻辑处理
    parent::report($exception);
}

2. 可选:在自定义404页面展示请求URL

如果你想在自己的404页面上告诉用户“你访问的XX页面不存在”,可以在render方法里把请求URL传递到视图:

public function render($request, Throwable $exception)
{
    if ($exception instanceof \Symfony\Component\HttpKernel\Exception\NotFoundHttpException) {
        // 把请求URL传给自定义404视图
        return response()->view('errors.404', [
            'requestedUrl' => $request->fullUrl()
        ], 404);
    }

    return parent::render($request, $exception);
}

之后在resources/views/errors/404.blade.php里就可以直接用{{ $requestedUrl }}来显示用户访问的不存在的URL了。

3. 进阶:快速区分真人与机器人

要判断访问404的是真人还是机器人,最直接的方式是解析用户代理(User-Agent)。Laravel自带了agent()辅助函数,可以帮你快速识别:

// 在report方法的404处理逻辑里添加
$isRobot = agent()->isRobot();
// 然后把这个字段也加入日志或数据库
logger()->error('404 页面访问记录', [
    // ...其他字段
    '是否为机器人' => $isRobot ? '是' : '否'
]);

不过要注意,有些恶意机器人会伪装成普通浏览器的UA,如果你需要更精准的识别,可以结合IP黑名单或者专业的爬虫识别库,但大部分场景下agent()->isRobot()足够用了。

4. 进阶:将404记录存入数据库

如果想长期统计分析404请求,可以创建一个专门的模型来存储这些记录:

  1. 先创建迁移文件:
php artisan make:migration create_not_found_logs_table
  1. 在迁移文件里添加字段:
public function up()
{
    Schema::create('not_found_logs', function (Blueprint $table) {
        $table->id();
        $table->text('url');
        $table->text('user_agent')->nullable();
        $table->string('ip')->nullable();
        $table->boolean('is_robot')->default(false);
        $table->timestamps();
    });
}
  1. 创建对应的模型app/Models/NotFoundLog.php,然后在Handler的report方法里添加存储逻辑:
\App\Models\NotFoundLog::create([
    'url' => $requestUrl,
    'user_agent' => $userAgent,
    'ip' => $ipAddress,
    'is_robot' => agent()->isRobot()
]);

这样你就能随时通过数据库查询哪些URL被频繁访问(不管是真人误点还是机器人爬取),方便后续优化路由或者屏蔽恶意爬虫。

备注:内容来源于stack exchange,提问作者Hashim Aziz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.23 13:57:35