在Laravel 5.4中禁用请求验证重定向

Kei*_*owe 8 json request-validation laravel

所以我正在尝试为内部项目开发一个rest API,我遇到了一个问题,当表单请求验证失败时,它会显示@index响应.

所以我有两条路线;

Route::get('/api/clients', 'ClientController@index');
Route::post('/api/clients', 'ClientController@store');
Run Code Online (Sandbox Code Playgroud)

@index列出所有客户端,@store创建一个新客户端,我在方法上有一个表单请求验证器,@store它检查为客户端提供的名称.

我想要的是当验证器失败时,它会显示带有验证错误的JSON响应.但我认为它发生的是验证失败,因此它重定向回同一页面,但重定向GET不是POST,所以它列出了所有客户端.

我知道你可以设置你的标题,使它看起来像一个ajax请求,它将正确显示JSON响应,但我希望它显示JSON响应,无论它是否是ajax.

我已经尝试覆盖response我的验证器中的方法,该方法不起作用,我已经尝试wantsJson在验证器中设置方法以返回true,这再次无效.

非常感谢帮助.

代码如下......

web.php

Route::get('/api/clients', 'ClientController@index');
Route::get('/api/clients/{client}', 'ClientController@show');
Route::post('/api/clients', 'ClientController@store');
Route::put('/api/clients/{id}', 'ClientController@update');
Route::delete('/api/clients/{id}', 'ClientController@delete');
Run Code Online (Sandbox Code Playgroud)

ClientController.php

namespace App\Http\Controllers;

use App\Client;
use App\Http\Requests\ClientRequest;

class ClientController extends Controller
{

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(ClientRequest $request)
    {
        return Client::create([
            'title'   => request('title'),
            'user_id' => auth()->id()
        ]);
    }
Run Code Online (Sandbox Code Playgroud)

ClientRequest.php

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class ClientRequest extends FormRequest
{

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

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'title' => 'required'
        ];
    }

    /**
     * Get the failed validation response for the request.
     *
     * @param array $errors
     * @return JsonResponse
     */
     public function response(array $errors)
     {
         dd('exit'); // Doesn't work
     }
}
Run Code Online (Sandbox Code Playgroud)

iCo*_*ers 26

你可以这样试试

请在表单请求中首先使用以下内容

use Illuminate\Contracts\Validation\Validator;
use Illuminate\Http\Exceptions\HttpResponseException;
Run Code Online (Sandbox Code Playgroud)

然后

protected function failedValidation(Validator $validator) {
        throw new HttpResponseException(response()->json($validator->errors(), 422));
    }
Run Code Online (Sandbox Code Playgroud)

现在,如果您尝试验证,那么它将返回

{
"title": [
"The  title field is required."
]
}
Run Code Online (Sandbox Code Playgroud)

  • 这按预期工作,谢谢百万! (2认同)
  • 正是我在寻找的东西! (2认同)
  • 在网上看到一个经过深思熟虑的 Laravel 问题和匹配的答案真是令人耳目一新! (2认同)
  • 抛出错误是个好主意。谢谢 :) (2认同)

Chr*_*hvh 11

在发出请求时,我们应该发送标题信息.

Accept: application/json
Content-Type: application/json
Run Code Online (Sandbox Code Playgroud)

就是这样,现在laravel不会重定向并将错误消息作为JSON发送.

  • 您可以在集合的预请求脚本中设置自动设置“Accept”标头:“pm.request.headers.upsert({ key: 'Accept', value: 'application/json' })` (2认同)

小智 9

试试这个

打开app/Exceptions/Handler.php文件

包括使用

use Illuminate\Validation\ValidationException;
Run Code Online (Sandbox Code Playgroud)

然后添加方法

    /**
     * Create a response object from the given validation exception.
     *
     * @param  \Illuminate\Validation\ValidationException  $e
     * @param  \Illuminate\Http\Request  $request
     * @return \Symfony\Component\HttpFoundation\Response
     */
    protected function convertValidationExceptionToResponse(ValidationException $e, $request)
    {
        if ($e->response) {
            return $e->response;
        }

        return response()->json($e->validator->errors()->getMessages(), 422);
    }
Run Code Online (Sandbox Code Playgroud)

现在您可以像ajax请求那样获得标准的validationFailure响应


Ami*_*aei 6

两种方法可以处理验证器错误,我的建议是第二种方法

1.第一种方法,当验证失败时(在控制器中)简单地返回一个错误。例子:

    try {
        request()->validate([
            'input1' => 'required',
            'input2' => 'string|min:5',
        ]);

    } catch (\Illuminate\Validation\ValidationException $e){
        return response('The given data was invalid.', 400);

    }
Run Code Online (Sandbox Code Playgroud)

方便又干净。

2.第二种方式是向用户显示完整错误(在控制器中),如下所示:

    use Illuminate\Support\Facades\Validator;

    $validator = Validator::make(request()->all(), [
         'id' => 'required|integer',
         'description' => 'string'
    ]);

    // return array of errors to client with status code 400
    if ($validator->fails())
        return response($validator->messages()->toArray(), 400);
Run Code Online (Sandbox Code Playgroud)


小智 6

只需使用此特征即可防止FormRequest验证后重定向。以下特征还带来了一些有用的公共方法,例如:

  • validatorPasses()
  • validatorFails()
  • validatorErrors()
  • respondWithErrorsJson(int $code = 422)
  • redirectWithErrors()- 恢复默认的 Laravel FomrRequest 行为

特征

namespace App\Http\Requests;

use Illuminate\Contracts\Validation\Validator;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Support\MessageBag;
use Illuminate\Validation\ValidationException;

trait PreventsRedirectWhenFailedTrait
{
    /**
     * Default self::failedValidation() Laravel behavior flag.
     *
     * @var bool
     */
    private $defaultFailedValidationRestored = false;

    /**
     * Check for validator success flag.
     *
     * @return bool
     */
    public function validatorPasses(): bool
    {
        return !$this->validatorFails();
    }

    /**
     * Check for validator fail flag.
     *
     * @return bool
     */
    public function validatorFails(): bool
    {
        return $this->getValidatorInstance()->fails();
    }

    /**
     * @return MessageBag
     */
    public function validatorErrors(): MessageBag
    {
        return $this->getValidatorInstance()->errors();
    }

    /**
     * Respond with validator errors in JSON format.
     *
     * @param  int  $code
     */
    public function respondWithErrorsJson(int $code = 422): void
    {
        if ($this->validatorFails()) {
            throw new HttpResponseException(
                response()->json(['errors' => $this->getValidatorInstance()->errors()], $code)
            );
        }
    }

    /**
     * Restore and apply default self::failedValidation() method behavior.
     *
     * @throws ValidationException
     */
    public function redirectWithErrors(): void
    {
        $this->defaultFailedValidationRestored = true;

        $this->failedValidation($this->getValidatorInstance());
    }

    /**
     * Handle a failed validation attempt.
     *
     * @param  \Illuminate\Contracts\Validation\Validator  $validator
     * @return void
     *
     * @throws \Illuminate\Validation\ValidationException
     */
    protected function failedValidation(Validator $validator): void
    {
        if ($this->defaultFailedValidationRestored) {
            throw (new ValidationException($validator))
                ->errorBag($this->errorBag)
                ->redirectTo($this->getRedirectUrl());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

使用示例:

namespace App\Http\Requests;

use Auth;
use Illuminate\Foundation\Http\FormRequest;

class AuthRequest extends FormRequest
{
    use PreventsRedirectWhenFailedTrait;

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

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules(): array
    {
        return [
            'email' => 'required|email|exists:users',
            'password' => 'required',
            'remember_me' => 'integer',
        ];
    }
}
Run Code Online (Sandbox Code Playgroud)

在你的控制器内部:

public function authenticate(AuthRequest $request)
    {
        if ($request->validatorPasses()) {
            $data = $request->validated();
            /* your logic */
        } else {
            $errorBag = $request->validatorErrors();
        }

        // or
        if ($request->validatorFails()) {
            // your logic
        }
}
Run Code Online (Sandbox Code Playgroud)

希望您会发现这很有帮助。