You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel 9中Swagger返回HTML页面而非验证错误问题

问题解决:Swagger触发Laravel验证时返回HTML而非JSON

问题场景

Laravel 9项目中配置Swagger后,接口传入正确参数时运行正常;但传入错误参数触发验证时,Postman可正常返回验证错误的JSON响应,而Swagger却返回HTML页面。

Swagger注解代码

/**
 * @OA\Put(
 *      path="/api/admins/{id}/status",
 *      operationId="updateAdminStatus",
 *      tags={"Admin"},
 *      security={ {"sanctum": {} }},
 *      summary="Update admin status",
 *      description="Update an existing admin user's status by ID",
 *      @OA\Parameter(
 *          name="id",
 *          in="path",
 *          required=true,
 *          description="Admin ID",
 *          @OA\Schema(type="integer", format="int32", example=1)
 *      ),
 *      @OA\RequestBody(
 *          required=true,
 *          description="Pass admin data",
 *          @OA\JsonContent(
 *              required={"status"},
 *              @OA\Property(property="status", type="integer", format="int32", example=0)
 *          )
 *      ),
 *      @OA\Response(
 *          response=200,
 *          description="Admin status updated successfully"
 *      ),
 *      @OA\Response(
 *          response=400,
 *          description="Invalid input data"
 *      ),
 *      @OA\Response(
 *          response=401,
 *          description="Unauthenticated"
 *      ),
 *      @OA\Response(
 *          response=404,
 *          description="Admin not found"
 *      ),
 *      @OA\Response(
 *          response=500,
 *          description="Internal server error"
 *      )
 * )
 */

验证代码

$validatedData = $request->validate([
    'status' => 'required|in:0,1'
]);
throw_unless($validatedData);

响应对比

  • Postman响应:
{
    "message": "The status field is required.",
    "errors": {
        "status": [
            "The status field is required."
        ]
    }
}
  • Swagger响应:返回HTML错误页面

问题原因

Laravel的默认验证异常处理会根据请求的Accept头判断响应格式:

  • Postman发送的请求Accept头为application/json,所以返回JSON格式错误
  • Swagger UI发送的请求Accept头包含text/html,Laravel因此返回了HTML错误页面

解决方案

方案1:局部修改验证逻辑(单接口)

放弃$request->validate()的自动异常抛出,改用Validator facade手动验证并强制返回JSON响应:

use Illuminate\Support\Facades\Validator;

// 手动创建验证器
$validator = Validator::make($request->all(), [
    'status' => 'required|in:0,1'
]);

// 验证失败时返回JSON
if ($validator->fails()) {
    return response()->json([
        'message' => 'Invalid input data',
        'errors' => $validator->errors()
    ], 400);
}

// 验证通过后继续业务逻辑
$validatedData = $validator->validated();

方案2:全局修改API路由的异常响应(所有接口)

在app/Exceptions/Handler.php中添加验证异常的自定义处理,针对API路由强制返回JSON:

use Illuminate\Validation\ValidationException;

public function register()
{
    $this->renderable(function (ValidationException $e, $request) {
        // 判断当前请求是否为API路由
        if ($request->is('api/*')) {
            return response()->json([
                'message' => $e->getMessage(),
                'errors' => $e->errors()
            ], $e->status);
        }
    });
}

补充说明

如果使用Laravel Sanctum且Swagger已配置正确的认证,上述方案即可解决问题。无需额外在验证逻辑中添加try-catch,因为$request->validate()本身会自动抛出ValidationException,我们只需修改该异常的响应格式即可。

内容的提问来源于stack exchange,提问作者Michalle Rodriguez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 04:55:41