Laravel 5:当请求需要 JSON 时处理异常

2022-08-30 11:05:35

我正在通过Laravel 5上的AJAX上传文件。除了一件事,我几乎一切都在工作。

当我尝试上传一个太大的文件(大于,我得到一个TokenMismatchException抛出。upload_max_filesizepost_max_size

但是,这是可以预料到的,因为我知道如果超过这些限制,我的输入将为空。空输入,意味着没有收到,因此为什么负责验证CSRF令牌的中间件大惊小怪。_token

然而,我的问题不在于抛出这个异常,而在于它是如何呈现的。当这个异常被Laravel捕获时,它会吐出通用Whoops页面的HTML(由于我处于调试模式,因此具有堆栈跟踪负载)。

处理此异常的最佳方法是什么,以便通过 AJAX(或请求 JSON 时)返回 JSON,同时保持默认行为?


编辑:无论引发何种异常,这似乎都会发生。我刚刚尝试通过AJAX(数据类型:JSON)向不存在的“页面”发出请求,试图获取404,并且发生了同样的事情 - 返回HTML,没有任何JSON友好。


答案 1

我将考虑到@Wader给出的答案以及@Tyler Crompton的评论,自己尝试一下:

应用/异常/处理程序.php

/**
 * Render an exception into an HTTP response.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \Exception $e
 * @return \Illuminate\Http\Response
 */
public function render($request, Exception $e)
{
    // If the request wants JSON (AJAX doesn't always want JSON)
    if ($request->wantsJson()) {
        // Define the response
        $response = [
            'errors' => 'Sorry, something went wrong.'
        ];

        // If the app is in debug mode
        if (config('app.debug')) {
            // Add the exception class name, message and stack trace to response
            $response['exception'] = get_class($e); // Reflection might be better here
            $response['message'] = $e->getMessage();
            $response['trace'] = $e->getTrace();
        }

        // Default response of 400
        $status = 400;

        // If this exception is an instance of HttpException
        if ($this->isHttpException($e)) {
            // Grab the HTTP status code from the Exception
            $status = $e->getStatusCode();
        }

        // Return a JSON response with the response array and status code
        return response()->json($response, $status);
    }

    // Default to the parent class' implementation of handler
    return parent::render($request, $e);
}

答案 2

在您的应用程序中,您应该具有 .在该文件中,您可以处理中间件的运行方式。因此,您可以检查请求是否为ajax,并按照您喜欢的方式处理它。app/Http/Middleware/VerifyCsrfToken.php

交替地,可能是一个更好的解决方案,是编辑异常处理程序以返回json。请参阅,下面类似的东西将是一个起点app/exceptions/Handler.php

public function render($request, Exception $e)
{
    if ($request->ajax() || $request->wantsJson())
    {
        $json = [
            'success' => false,
            'error' => [
                'code' => $e->getCode(),
                'message' => $e->getMessage(),
            ],
        ];

        return response()->json($json, 400);
    }

    return parent::render($request, $e);
}

推荐