Laravel 404和500的API和网站中的不同响应(JSON和网页)?
我想显示API和网站的不同响应。在api响应中,我想显示json响应,其中404和500表示主要用于路由的异常类型 如果一个用户试图请求一个路由,但没有找到路由,我想在json响应中为API显示一个响应,在Web页面中为网站显示一个响应 我知道并尝试将代码放入Laravel 404和500的API和网站中的不同响应(JSON和网页)?,laravel,laravel-5.4,Laravel,Laravel 5.4,我想显示API和网站的不同响应。在api响应中,我想显示json响应,其中404和500表示主要用于路由的异常类型 如果一个用户试图请求一个路由,但没有找到路由,我想在json响应中为API显示一个响应,在Web页面中为网站显示一个响应 我知道并尝试将代码放入app/Exceptions/Handler.php public function render($request, Exception $exception) { if ($exception instanceof NotFou
app/Exceptions/Handler.php
public function render($request, Exception $exception)
{
if ($exception instanceof NotFoundHttpException) {
if ($request->expectsJson()) {
return response()->json(['error' => 'Not Found'], 404);
}
return response()->view('404', [], 404);
}
return parent::render($request, $exception);
}
public function render($request, Exception $exception)
{
// Give detailed stacktrace error info if APP_DEBUG is true in the .env
if ($request->wantsJson()) {
// Return reasonable response if trying to, for instance, delete nonexistent resource id.
if ($exception instanceof \Illuminate\Database\Eloquent\ModelNotFoundException) {
return response()->json(['data' => 'Resource not found'], 404);
}
if ($_ENV['APP_DEBUG'] == 'false') {
return response()->json(['error' => 'Unknown error'], 400);
}
}
return parent::render($request, $exception);
}
但是失败了。有人能帮助我如何为错误页面设置不同的响应。试试这个。
public function render($request, Exception $exception)
{
if ($request->ajax()) {
return \Response::json([
'success' => false,
'message' => $exception->getMessage(),
], $exception->getCode());
} else {
return parent::render($request, $exception);
}
}
预期
JSON
是关于标题的,我不喜欢API
错误的解决方案,您可以通过浏览器访问API
。我的解决方案大多数情况下是通过URL
路由进行过滤,因为它以“api/…”
开头,可以像这样执行$request->is('api/*')
如果您的路由不是带有/api
前缀的路由,那么这将不起作用。更改逻辑以适合您自己的结构
public function render($request, Exception $exception)
{
if ($exception instanceof NotFoundHttpException) {
if ($request->is('api/*')) {
return response()->json(['error' => 'Not Found'], 404);
}
return response()->view('404', [], 404);
}
return parent::render($request, $exception);
}
我使用的是Laravel5.5.28,并在
app/Exceptions/Handler.php
public function render($request, Exception $exception)
{
if ($exception instanceof NotFoundHttpException) {
if ($request->expectsJson()) {
return response()->json(['error' => 'Not Found'], 404);
}
return response()->view('404', [], 404);
}
return parent::render($request, $exception);
}
public function render($request, Exception $exception)
{
// Give detailed stacktrace error info if APP_DEBUG is true in the .env
if ($request->wantsJson()) {
// Return reasonable response if trying to, for instance, delete nonexistent resource id.
if ($exception instanceof \Illuminate\Database\Eloquent\ModelNotFoundException) {
return response()->json(['data' => 'Resource not found'], 404);
}
if ($_ENV['APP_DEBUG'] == 'false') {
return response()->json(['error' => 'Unknown error'], 400);
}
}
return parent::render($request, $exception);
}
这期望您的API调用将有一个带有键Accept
和值application/json
的头
然后,不存在的web路由返回预期的
很抱歉,找不到您要查找的页面
一个不存在的API资源返回一个JSON 404负载
找到了
您可以将其与查找
NotFoundHttpException
实例的答案结合起来,以捕获500。不过,我想最好使用堆栈跟踪。无需再次为Laravel升级而忙碌。您只需要在routes/api.php中定义此方法
我只是想在上述答案的基础上添加一个替代方案,所有这些似乎都很有效 在遇到同样的问题并深入挖掘之后,我采取了一种稍微不同的方法:
- 异常句柄调用父::呈现(…)。如果查看该函数,如果您的请求指示它
[请参阅]wantsJson()
- 现在,为了将所有响应(包括异常)转换为json,我使用了来自的Jsonify中间件思想,但将其应用于api MiddlewareGroup,该api默认分配给RouteServiceProvider::mapApiRoutes()
app/Http/Middleware/Jsonify.php
<?php
namespace App\Http\Middleware;
use Closure;
class Jsonify
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if ( $request->is('api/*') ) {
$request->headers->set('Accept', 'application/json');
}
return $next($request);
}
}
protected $middlewareGroups = [
...
'api' => [
'jsonify',
'throttle:60,1',
'bindings',
],
...
];
结果是,对于属于“api”组的任何请求,都会加载中间件。如果请求url以
api/
开头(我认为这有点多余),那么Jsonify中间件会添加头。这将告诉ExceptionHandler::render()我们需要json输出 这对我很有用,还添加了使用Symfony\Component\HttpKernel\Exception\NotFoundHttpException代码>谢谢“X-Requested-With”:“XMLHttpRequests”需要添加标题,否则laravel请求不会检测为ajex调用,这就是为什么返回页面。遗憾的是,这在大多数情况下都有效,但在某些情况下不起作用:如果您从策略或网关获得“未授权”,则您的中间件可能尚未加载。如果没有加载jsonify,您将获得非json输出,除非您相应地设置了头(接受Application/json)。因此,您可以使用这个答案,只是要注意不足……如果您要将其添加到api
中间件组,则无需在请求URL中检查/api
。路由服务提供商将api
中间件组和/api
前缀应用于api.php
中列出的路由。使用GET方法可以很好地工作。但与其他方法(POST、PUT等)相同的url将返回405 methodNotLowed。我建议通过这种方式在api路由的末尾定义自定义回退路由()对于Laravel 8,请参见以下答案