Laravel 表单验证在失败时重定向到 Web 路由

Laravel Form Validation redirecting to web routes when it fails

提问人:Thiago Maciel 提问时间:11/5/2023 更新时间:11/5/2023 访问量:58

问:

我有一个 Laravel 应用程序 (v10.30.1) 这个 api 路由块:

<?php

use App\Http\Controllers\EmployeeController;
use Illuminate\Support\Facades\Route;

Route::prefix('v1')->group(function () {
    Route::resource('employees', EmployeeController::class)
        ->only(['store', 'index', 'update']);
});```

This method in EmployeeController:

/**
 * Update an existing employee.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \App\Models\Employee  $employee
 * @return \Illuminate\Http\JsonResponse
 */
public function update(EmployeeUpdateRequest $request, Employee $employee): JsonResponse
{
    $employee->update($request->validated());

    return response()->json($employee, 200);
}

This is the EmployeeUpdateRequest:

/**
 * Determine if the user is authorized to make this request.
 */
public function authorize(): bool
{
    return true;
}

/**
 * Get the validation rules that apply to the request.
 *
 * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
 */
public function rules(): array
{
    return [
        'cpf' => 'required|size:11|unique:employees',
    ];
}```

当验证通过时,它工作正常,但当它失败时,它不会以 json 格式返回错误消息,而是重定向到主 Web 路由。

如果我像这样每年创建验证器,它可以正常工作,但现在我需要使用表单请求:

    /**
     * Update an existing employee.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\Employee  $employee
     * @return \Illuminate\Http\JsonResponse
     */
    public function update(Request $request, Employee $employee): JsonResponse
    {

        $validator = Validator::make($request->all(), [
            'cpf' => 'size:11|unique:employees',
        ]);

        if ($validator->fails()) {
            return response()->json(['errors' => $validator->errors()], 400);
        }
        $employee->update($request->all());

        return response()->json($employee, 200);
    }```

I'm expecting to use a form request and just receive the error messages when it happens instead of be redirected to web home route
Laravel 验证 Laravel-formrequest

评论

0赞 lagbox 11/5/2023
系统应该如何知道您不需要重定向?它如何知道您向“API”发出的请求应该以不同的方式处理?除了 URL 之外,此请求与对应用程序的任何其他普通 Web 请求有什么区别?
0赞 Adi 11/5/2023
我很好奇为什么而不是$validator = Validator::make($request->all(), ['cpf'=>'size:11|unique:employees',]);$validator = Validator::make($request->all(), $request->rules());
0赞 lagbox 11/5/2023
@Adi,因为该代码不使用 FormRequest
0赞 Adi 11/5/2023
哦,对不起,我以为你一定使用了 EmployeeUpdateRequest 这样的东西。use App\Http\Requests\EmployeeUpdateRequest;
0赞 Adi 11/5/2023
你能试试这个 stackoverflow.com/questions/73836381/ 吗......?我知道问题陈述是不同的,但你能在表单请求中覆盖 failedValidation 方法吗?

答:

-1赞 shahin 11/5/2023 #1

我认为如果您在标头请求中设置,问题就会得到解决。Content-Type:application/json

评论

1赞 Adi 11/5/2023
使用 JSON 时,这是一个很好的做法,但这并不能直接解决导致重定向的验证错误问题,也不会直接解决此处的问题。
0赞 lagbox 11/5/2023
也许您的意思是“接受”标题?正如此请求所说,它将接受特定内容类型的响应
0赞 Adi 11/5/2023
@lagbox我碰巧阅读了您删除的评论,但随后需要首先深入研究中间件,确保没有,然后检查是否如何处理验证错误,然后检查路由/控制器,如果操作在失败时返回 JSON,这就是这个答案。我可能错过了更多的检查,但这些都很少RedirectIfAuthenticated app/Exceptions/Handler.php
0赞 lagbox 11/5/2023
如果操作返回 JSON,则不是,操作返回的内容无关紧要......“当您的应用程序抛出异常并且传入的 HTTP 请求需要 JSON 响应时,Laravel 将自动为您格式化错误消息并返回 422 Unprocessable Entity HTTP 响应。”Illuminate\Validation\ValidationException
0赞 Adi 11/5/2023
@lagbox是的,您是对的,但是不需要确保正确配置路由、中间件和控制器操作以及 api/curl 请求,其中 OP 可以将标头设置为接受 JSON,并且没有冲突行为导致重定向。我的意思是它可能会也可能不会解决问题,因为问题可能出在以下任何一件事上。
-1赞 Adi 11/5/2023 #2

因此,根据我们在评论中的对话和这里的一些上下文,将 failedValidation() 函数添加到请求时会出现 Illuminate\Contracts\Validation\Validator 错误,但 passedValidation() 工作正常?也许您可以尝试像这样覆盖表单请求failedVaidation

protected function failedValidation(Validator $validator) {
    $response = new JsonResponse(['errors' => $validator->errors()], 400);
    throw new \Illuminate\Validation\ValidationException($validator, $response);
}

希望这会有所帮助

评论

0赞 Adi 11/6/2023
@Thiago Maciel 这不能解决问题吗?这之后有什么错误?