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 异常。
我正在使用中间件来解析模板的输出。这适用于所有页面。
然而,当我想显示 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 异常。