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/json
的Accept
标头添加到标头选项卡中的邮递员请求中,如下所示::
这将告诉 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
类型的 NotFoundHttpException
和 render
它。为了防止这种行为,您可以这样做。
在 '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?的主要内容,如果未能解决你的问题,请参考以下文章