【问题标题】:Get Response body from response object in Middleware从中间件中的响应对象获取响应正文
【发布时间】:2018-10-04 13:00:27
【问题描述】:

我有一个中间件来记录所有请求和响应(用于 API)。但是终止方法响应对象中没有显示响应。

class Logger
{

    public function handle($request, Closure $next)
    {
        return $next($request);
    }

    public function terminate($request, $response)
    {
        Log::info('ApiLog done===========================');
        Log::info('URL: ' . $request->fullUrl());
        Log::info('Method: ' . $request->getMethod());
        Log::info('IP Address: ' . $request->getClientIp());
        Log::info("Data: ",[$request->all()]);
        // Log::info("Query String: ", [$request->query()]);
        Log::info("Response".$response->getContent());
    }
}

但是 $response->getContent() 返回 null。 首先,我尝试仅使用句柄处理请求并获取响应,然后使用记录它

public function handle($request, Closure $next)
{
    $response = $next($request);

    Log::response("",[$response])

    return $response;
}

但对象不包含正文。它只有状态和标题信息。 您能帮我获取响应正文吗

【问题讨论】:

  • 我现在尝试终止我的项目,它会在您使用它时打印出整个主体。你有在app/Http/Kernel.php注册的中间件作为路由还是全局中间件?
  • 注册为middlewareGroup
  • 然后在路由中使用该中间件进行一组路由

标签: laravel laravel-5.4


【解决方案1】:

我将在这里回复以分享更大的代码而不是评论。所以根据文档,它应该在$routeMiddleware$middleware 中,因为如果你打开框架Kernel 你会看到这个:

$middlewares = $this->app->shouldSkipMiddleware() ? [] : array_merge(
        $this->gatherRouteMiddleware($request),
        $this->middleware
    );

在那些terminate 函数被调用。

【讨论】:

  • 我也试过把它放在 $routeMiddleware / $middleware 中。仍然没有显示响应正文。在响应对象上记录的响应和 getContent() 方法都有空主体
  • ResponseHTTP/1.1 200 OK Cache-Control: no-cache, private Content-Type: text/html;字符集= UTF-8日期:星期四,2018年10月4日13时48分十秒GMT的Set-Cookie:laravel_session = eyJpdiI6Ik9MT3RFWWFwd0dQZXQwQXJ3anFyb0E9PSIsInZhbHVlIjoiRHg0RVdXdzlVTWZ3b2p3Y0tuS3JCWUNKbEM2OVJaSlBRS2xPRmlRUk45NU93bUdhRFBjcGtVVWN6SVoyemlzdTdYa29iMmU1MzBGUFRsa3hZaFFHa0E9PSIsIm1hYyI6Ijg5NDlhYmYxNzc2NDU4ZjA1ZGI3MGU5MTQ0NmMyNWI3MDI1MjBlZDgxZTBlNDNjMzNiMjYwNWRlM2U1MWFhNDgifQ%3D%3D;到期=格林威治标准时间 2018 年 10 月 4 日星期四 15:48:10;最大年龄=7200;路径=/; httponly
  • 这是响应对象,$response->getContent() 什么也不显示
  • 在句柄和终止方法中都进行了测试
  • 您能分享一下您从控制器操作返回的内容吗?
【解决方案2】:

这是来自调试的 HttpResponse 的 print_r

Illuminate\Http\Response Object
(
    [headers] => Symfony\Component\HttpFoundation\ResponseHeaderBag Object
        (
            [computedCacheControl:protected] => Array
                (
                    [no-cache] => 1
                    [private] => 1
                )

            [cookies:protected] => Array
                (
                )

            [headerNames:protected] => Array
                (
                    [cache-control] => Cache-Control
                    [date] => Date
                    [content-type] => Content-Type
                )

            [headers:protected] => Array
                (
                    [cache-control] => Array
                        (
                            [0] => no-cache, private
                        )

                    [date] => Array
                        (
                            [0] => Thu, 04 Oct 2018 14:17:16 GMT
                        )

                    [content-type] => Array
                        (
                            [0] => text/html; charset=UTF-8
                        )

                )

            [cacheControl:protected] => Array
                   (
                )

        )

    [content:protected] => foobar content
    [version:protected] => 1.1
    [statusCode:protected] => 200
    [statusText:protected] => OK
    [charset:protected] => 
    [original] => foobar content
    [exception] => 
)

属性content:protected 被替换为“foobar content”,因为它的大小很大。您可以调用$response->setContent('foobar content');设置内容值或调用$response->getContent();接收内容值。

如果$response->getContent(); 返回null,那么你必须检查$response 的对象类型。也许不是\Illuminate\Http\Response

这是我的测试中间件:

class RedirectIfAuthenticated
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  string|null  $guard
     * @return mixed
     */
    public function handle($request, Closure $next, $guard = null)
    {
        if (Auth::guard($guard)->check()) {
            return redirect('/home');
        }

        /** @var Illuminate\Http\Response $response */
        $response = $next($request);
        $foo = $response->getContent();

        return $response;
    }
}

希望对您有所帮助。祝你有美好的一天!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-16
    • 2013-08-07
    • 1970-01-01
    • 2018-12-19
    • 1970-01-01
    • 2022-08-24
    • 2017-12-30
    • 1970-01-01
    相关资源
    最近更新 更多