后置中间件在 Laravel 中指在 $next($request) 执行后对响应对象进行修改的中间件。需实现 handle 方法,调用 $next($request) 获取响应,再修改其 Header、状态码或内容,最后返回响应;不可提前输出或终止脚本。

在 Laravel 中,后置中间件(after middleware)是指在请求处理完成、响应已生成但尚未发送给客户端时执行的中间件。这类中间件可以读取并修改响应内容、状态码、Header 等,常用于日志记录、响应压缩、CSP 头添加、JSON 格式统一包装等场景。
如何定义一个后置中间件
Laravel 默认中间件都是“前置”行为(即在控制器执行前运行),但只要不在中间件中调用 $next($request) 或在调用后继续操作响应,就无法实现“后置”。真正的后置逻辑必须放在 $next($request) 之后,并对返回的 Response 实例进行修改。
- 中间件类需实现
handle方法 - 必须调用
$next($request)获取响应对象 - 在
$next()返回后对$response进行修改,再返回它 - 不要在中间件中直接 echo/print 或调用
exit,否则会中断响应生命周期
示例:添加自定义 Header 并修改 JSON 响应体
比如你想为所有 JSON 响应统一添加 X-App-Version 头,并在开发环境自动包裹一层 {"data": ...}:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
class WrapJsonResponse
{
public function handle(Request $request, Closure $next): Response
{
$response = $next($request);
// 只对 JSON 响应生效
if ($response->headers->get('Content-Type') === 'application/json') {
// 添加 Header
$response->headers->set('X-App-Version', config('app.version'));
// 开发环境下包装 data 字段
if (app()->environment('local')) {
$content = $response->getContent();
$data = json_decode($content, true) ?: [];
$wrapped = json_encode(['data' => $data], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$response->setContent($wrapped);
}
}
return $response;
}
}
注册中间件到全局或分组路由
在 app/Http/Kernel.php 中注册:
- 全局后置(应用到所有请求):加到
$middleware数组末尾(顺序重要) - 路由组后置:在
routes/web.php或routes/api.php中使用middleware()链式调用 - 注意中间件执行顺序:数组靠前的中间件,其
$next()调用更早,因此它的后置逻辑实际更“靠后”
// 在 Kernel.php 的 $middleware 数组中(推荐放最后)
protected $middleware = [
// ... 其他中间件
\App\Http\Middleware\WrapJsonResponse::class,
];
注意事项与常见陷阱
-
响应已流式输出时不可修改:如果响应已通过
stream()或大文件下载方式发送, setContent() 无效 -
避免重复包装:多次调用同一中间件可能导致嵌套
{"data": {"data": ...}},建议加标记判断 -
状态码和 Header 修改要谨慎:如修改了
401为200,可能破坏前端鉴权逻辑 -
中间件不感知控制器返回类型:Laravel 响应对象是统一的,无论你 return view / response()->json() / redirect(),最终都转为
Illuminate\Http\Response实例


















