Laravel - 当 API 路由错误或找不到时如何显示 JSON?

Posted

技术标签:

【中文标题】Laravel - 当 API 路由错误或找不到时如何显示 JSON?【英文标题】:Laravel - How to show JSON when API route is wrong or not found? 【发布时间】:2019-04-16 04:22:48 【问题描述】:

我使用 Laravel 创建 API 并使用邮递员检查我的 API。当我在邮递员中输入正确的 URL 时,它工作正常,但是当我输入错误的 URL 时,它显示 html 和 Laravel 404 错误,我想以 JSON 格式返回一条消息,我该怎么做。

【问题讨论】:

它是 404 的事实是否还没有传达足够的信息?调用者应该很清楚问题是什么,不是吗? 404 表示“您要求的内容不存在”......客户端可以检测到状态代码并使用它来决定下一步做什么。您还想提供哪些其他信息? @ADyson 我想你没有明白我的意思,我是说当我的 URL 在邮递员中是 http://localhost:8005/api/login 时,它会显示令牌和值,但是当我的 URL 是 http://localhost:8005/api/log 时,这会显示一些 HTML 和 Laravel 404错误页面,我这次要返回JSON格式的消息。像“Messege”=>“未找到” 我的意思是你不需要 - 事实上它是 404 应该足以让客户知道该做什么。期望 JSON 的客户端无论如何都不会尝试显示 HTML。如果客户端遇到 HTTP 错误,它会停止处理并处理该错误。它可以丢弃 HTML。如果您打算在 JSON 中输入的只是“未找到”,那是多余的 - 每个人都已经知道 404 的含义。我认为您不需要这样做-您会付出很多努力而没有实际收获。也许我错了 - 你能告诉我你的客户端应用程序将如何从中受益吗? @ADyson 没有客户端,这是我的任务,我谷歌了很多,发现我必须更新我的Exceptions/handler.php 但它不起作用,这就是我在这里的原因。 “没有客户,”...总是有客户。否则如何提出请求? “这是我要做的任务”。为什么?究竟是为了什么目的?如果你想这样做,你必须有一些理由,为什么你认为这会对阅读回复的人有所帮助。我的观点是,我不认为它提供了任何有用的功能,所以真的很少有理由花时间在它上面。从我第一条评论的赞成票来看,我不是唯一一个相信这一点的人。我试图帮助你阻止你把时间浪费在没有实用价值的事情上。 【参考方案1】:

您应该将设置为application/jsonAccept 标头添加到标头选项卡中的邮递员请求中,如下所示::

这将告诉 Laravel 你想要一个 json 响应,而不是 HTML。这同样适用于您的应用程序中的任何请求。

如您所见,这是在 Illuminate\Http\Response 对象上检查的,当设置有效负载时,它会检查是否应将其变形为 JSON:

/**
 * Set the content on the response.
 *
 * @param  mixed  $content
 * @return $this
 */
public function setContent($content)

    $this->original = $content;

    // If the content is "JSONable" we will set the appropriate header and convert
    // the content to JSON. This is useful when returning something like models
    // from routes that will be automatically transformed to their JSON form.
    if ($this->shouldBeJson($content)) 
        $this->header('Content-Type', 'application/json');

        $content = $this->morphToJson($content);
    

    // If this content implements the "Renderable" interface then we will call the
    // render method on the object so we will avoid any "__toString" exceptions
    // that might be thrown and have their errors obscured by PHP's handling.
    elseif ($content instanceof Renderable) 
        $content = $content->render();
    

    parent::setContent($content);

    return $this;

您可以找到代码here。

希望对你有所帮助。

【讨论】:

不,它告诉服务器您正在发送 JSON。它与响应无关。您可以设置一个“接受”标头来提示服务器您想要什么样的响应,但最终服务器会做出决定 @ADyson 你完全正确,这是我的一大失误。我已经修复了我的答案,感谢您的反馈。 好的,这样更好。但是,如果服务器无法使用 JSON 响应该请求(因为它没有执行此操作的代码和编程),那么请求就会失败,这并不是一个真正理想的结果。客户端必须确保端点可以提供 JSON。目前 OP 的端点没有这样做,您的答案也没有提供能够做到这一点的解决方案。 @ADyson 是的,但是这是面向 Laravel 的,并且框架使用该标头来格式化响应,我正在寻找代码的代码库,我会在找到后立即发布它。 @ADyson 这里简要记录了laravel.com/docs/5.7/lifecycle,因为 Laravel 拦截每个请求然后路由它,它也可以处理丢失的路由。【参考方案2】:

据我了解 OP 的要求,希望将 Not Found 异常呈现行为覆盖为 JSON 响应。

Laravel 实际上会生成一个 exception 类型的 NotFoundHttpExceptionrender 它。为了防止这种行为,您可以这样做。

在 'app\Exceptions\Handler.php' 中,您会看到一个函数

 /**
 * Render an exception into an HTTP response.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \Exception  $exception
 * @return \Illuminate\Http\Response
 */
public function render($request, Exception $exception)

    // comment this line and return JSON Response.
    //return parent::render($request, $exception);

    return json_encode(array("message" => $exception->getMessage())); // or you can 
 

PS:这不是最终解决方案,如果您只希望 API 返回 JSON 以防出现错误,这只是一种解决方法。

【讨论】:

如果被调用(错误地)的 URL 根本没有被 PHP 处理怎么办? @ADyson 你能举一个例子来反驳你的论点吗?其次,我的解决方案只会将异常返回为JSON 对象,而不是将其呈现为HTML @FarooqKhan 感谢您的回复,是的,我发现我必须在handler.php 中进行更改,就像我从 WEB 找到的那样 if ($exception instanceof NotFoundHttpException) return response()->json (['消息'=>'未找到']); return parent::render($request, $exception); @ADyson 你有一个有效的论据,但 OP 的问题更多是关于在Laravel 应用程序上具体落在 PHP 服务器上的内容。 @shashiverma 是的,我的解决方案对于所有异常都比较通用,如果您只希望 not-found-route 类型的场景返回 JSON,您可以通过匹配实例类型使其更精确。

以上是关于Laravel - 当 API 路由错误或找不到时如何显示 JSON?的主要内容,如果未能解决你的问题,请参考以下文章

javaweb 中 error-page

Laravel API 404 错误

Laravel API 路由 404 未找到修复?

Spring配置文件里xsd找不到时解决方案

在 laravel 5.6 中无法使用邮递员使用 api 路由

Laravel 5 API 路由向前端返回 500 错误