1

我的 Laravel 项目有很多控制器方法,它们只是不返​​回任何内容或void成功返回。我希望(更准确地说是需要)这些方法最终204 No Content向客户端返回响应。我想避免return response()->noContent()在我需要的地方添加每个控制器方法。但是,如果我不这样做,Laravel 会向200 OK客户端发送一个带有空正文的响应。

该方法Illuminate\Routing\Router::toResponse($request, $response)对此负责。该参数$response等于控制器方法的返回值。如果控制器方法不返回任何内容,则$response等于null。该方法toResponse($request, $response)将参数$response与不同的条件进行匹配,如果没有匹配项,则toResponse($request, $response)创建一个SymfonyResponse状态码为 200 和一个空正文。我想覆盖这个方法并添加另一个条件。如果$response === null,那么toResponse($request, $response)应该创建一个SymfonfyResponse状态码为 204 的。

我的主要问题是我没有找到任何信息如何使框架调用我自己的路由器类实现。

4

1 回答 1

1

找到了一个比覆盖Router. 我可以使用在控制器方法运行之后、但在响应发送到客户端之前修改响应的中间件:所谓的响应中间件(请参阅Laravel 文档“Middleware $ Responses”)。

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

/**
 * Ensures that responses with empty content return status code 204.
 *
 * This fixes a bug in Laravel.
 */
class FixStatusCode {
  /**
   * Handle an incoming request.
   *
   * @param Request  $request
   * @param \Closure $next
   *
   * @return Response
   *
   * @throws \InvalidArgumentException
   */
  public function handle(Request $request, Closure $next): Response {
    /** @var Response $response */
    $response = $next($request);
    
    if (empty($response->getContent())) {
      $response->setStatusCode(Response::HTTP_NO_CONTENT);
    }
    
    return $response;
  }
}

然后,我必须像在App\Http\Kernel::$middleware.

于 2021-12-11T16:49:53.430 回答