Laravel 5.0自定义404不使用中间件

Laravel 5.0 custom 404 does not use middleware

我正在使用中间件来解析模板的输出。这适用于所有页面。

然而,当我想显示 404(为此获得自定义页面)时,它不会将其视为 http 请求(我就是这么认为的),因为它没有通过中间件。

我的问题是,如何让所有请求都通过中间件。

错误页面不经过 routes.php。

Kernel.php 中将您的中间件从 $routeMiddleware 数组移动到 $middleware 数组。

此数组中的中间件将 运行 处理每个请求(在 5.1 中测试)。

在 Laravel 5.4 和一些较旧的版本中,您可以像这样修改文件 app/exceptions/Handler.php 和函数 render

if( is_a( $exception, \Symfony\Component\HttpKernel\Exception\NotFoundHttpException::class ) ) {
    return redirect()->route( 'error_404' );
}

// ... old code in the function ...

以这种方式,每一个 404 错误都被重定向到某个真实的路由,该路由与站点的其他路由一样。

您还可以提交当前请求中的任何数据以显示目标的合理错误。

对于像我这样在 2020 年因为这种奇怪行为而花费数小时的人...

现在 Laravel 有一种新乐器 «Fallback Routes»。

将此添加到 /routes/web.php

Route::fallback(function () {
    return view("404"); // template should exists
});

之后所有请求都将通过中间件。

我有一个用例,其中 api 路由需要始终 return json 响应。

所有路由return json响应(laravel通过$request->expectsJson()检查) 如果用户通过发送 accept: application/json header.

明确要求

但很多时候用户并没有发送 header,而是收到 html 响应。

至于我的用例,所有 api 路由将始终发送 json 响应 we can force the routes to return json,方法是使用中间件手动附加 accept: application/json header。

App\Http\Middleware\ForceJsonOnAPIs.php

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Str;

class ForceJsonOnAPIs
{
    /**
     * Handle an incoming request.
     *
     * @param Request $request
     * @param Closure $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next)
    {
        // Force Json accept type on api routes
        if ($request->is('api/*') && !Str::contains($request->header('accept'), ['/json', '+json'])) {
            $request->headers->set('accept', 'application/json,' . $request->header('accept'));
        }

        return $next($request);
    }
}

App\Http\Kernel.php

中注册中间件
// add the new middleware ForceJsonOnAPIs
protected $middleware = [
    \App\Http\Middleware\ForceJsonOnAPIs::class,

    // rest of the middleware,
];

重要提示: 你可以像web或者api一样在Kernel中把中间赋值给$middlewareGroups,但是当404异常时你会遇到麻烦。问题是 The error pages don't go through the routes.php(感谢上面的@Björn 回答)因此不会调用路由中间件,404 将 return html 响应。

验证或身份验证异常情况相同。

在我看来,最好在 $middleware 数组中分配中间件,并在中间件本身中处理路由检查。所有异常都会自动 return 更正 api 路由中的 json 异常。