【问题标题】:Laravel Lumen Ensure JSON responseLaravel Lumen 确保 JSON 响应
【发布时间】:2016-09-14 18:22:23
【问题描述】:

我是 Laravel 和 Lumen 的新手。我想确保我总是只得到一个 JSON 对象作为输出。我怎样才能在 Lumen 中做到这一点?

我可以使用response()->json($response); 获得 JSON 响应。但是当发生错误时,API 会给我text/html 错误。但我只想要application/json 回复。

提前致谢。

【问题讨论】:

    标签: php json api laravel lumen


    【解决方案1】:

    建议您添加一个将Accept 标头设置为application/json 的中间件,而不是接触异常处理程序。

    例如,您可以创建一个名为RequestsAcceptJson 的中间件并这样定义:

    <?php
    
    namespace App\Http\Middleware;
    
    use Closure;
    
    class RequestsAcceptJson
    {
        /**
         * Handle an incoming request.
         *
         * @param  \Illuminate\Http\Request  $request
         * @param  \Closure  $next
         * @return mixed
         */
        public function handle($request, Closure $next)
        {
            $acceptHeader = strtolower($request->headers->get('accept'));
    
            // If the accept header is not set to application/json
            // We attach it and continue the request
            if ($acceptHeader !== 'application/json') {
                $request->headers->set('Accept', 'application/json');
            }
    
            return $next($request);
        }
    }
    
    

    然后您只需将其注册为全局中间件,即可在对您的 api 的每个请求中运行。在 lumen 中,您可以通过在 bootstrap/app.php 中的中间件调用中添加类来做到这一点

    $app->middleware([
        App\Http\Middleware\RequestsAcceptJson::class
    ]);
    

    使用 Laravel 的过程几乎相同。现在错误处理程序将始终返回一个 json 而不是纯文本/html。

    【讨论】:

      【解决方案2】:

      我知道这是一个相当古老的问题,但我只是偶然发现了它。 默认情况下,如果请求者“想要”它,Lumen 会返回一个 JSON 响应。

      vendor/laravel/lumen-framework/src/Exceptions/Handler.php:110

      return $request->expectsJson()
          ? $this->prepareJsonResponse($request, $e)
          : $this->prepareResponse($request, $e);
      

      这归结为 vendor/illuminate/http/Concerns/InteractsWithContentTypes.php:52

      $acceptable = $this->getAcceptableContentTypes();
      return isset($acceptable[0]) && Str::contains($acceptable[0], ['/json', '+json']);
      

      这意味着如果您为“application/json”指定“接受”标头,流明将自动返回 JSON 响应。 例如curl -H "Accept: application/json" https://example.com/my-erroring-endpint

      使用它可以让您不必编写自定义错误处理程序。

      【讨论】:

        【解决方案3】:

        您需要调整异常处理程序 (app/Exceptions/Handler.php) 以返回所需的响应。

        这是可以做什么的一个非常基本的示例。

        public function render($request, Exception $e)
        {
            $rendered = parent::render($request, $e);
        
            return response()->json([
                'error' => [
                    'code' => $rendered->getStatusCode(),
                    'message' => $e->getMessage(),
                ]
            ], $rendered->getStatusCode());
        }
        

        【讨论】:

        • 感谢您的回答。但是我有一个小问题,我可以这样做吗? return response()-&gt;json(['code' =&gt; $rendered-&gt;getStatusCode(), 'message' =&gt; $e-&gt;getMessage()], $rendered-&gt;getStatusCode());我搜索了异常列表,但还没有找到。
        • 这对我来说很好。这是response()-&gt;json() 函数的签名。 github.com/laravel/lumen-framework/blob/5.2/src/Http/…
        • 请注意,此示例将始终返回 200 HTTP 代码。你可能不想要那个。例如,如果使用findOrFail()code 元素将正确显示404,但总体结果仍将是200,显然不是。要解决此问题,请将$rendered-&gt;getStatusCode() 作为第二个参数传递给json()
        【解决方案4】:

        基于@Wader 的答案的更准确的解决方案可以是:

        use Illuminate\Http\JsonResponse;
        
        public function render($request, Exception $e)
        {
            $parentRender = parent::render($request, $e);
        
            // if parent returns a JsonResponse 
            // for example in case of a ValidationException 
            if ($parentRender instanceof JsonResponse)
            {
                return $parentRender;
            }
        
            return new JsonResponse([
                'message' => $e instanceof HttpException
                    ? $e->getMessage()
                    : 'Server Error',
            ], $parentRender->status());
        }
        

        【讨论】:

        • 很好的完整答案,包括必要的课程。给我点赞
        • 对 Lumen 8 有同样的建议吗?谢谢
        猜你喜欢
        • 1970-01-01
        • 2019-05-01
        • 2018-01-19
        • 2017-06-19
        • 2014-04-16
        • 2015-11-14
        • 2019-06-25
        • 2021-06-05
        • 2015-10-30
        相关资源
        最近更新 更多