MethodNotAllowedHttpException 在 Laravel 5.5 上使用表单请求验证
MethodNotAllowedHttpException using Form Request Validation on Laravel 5.5
这很奇怪,当我在 Laravel 5.5 上使用 Form Request Validation 时,我所有的 post 请求都将是 405 Method Not Allowed,但是当我使用标准验证时变得正常,这是我的代码是:
php artisan route:list 值
+--------+----------+----------------------------------------+--------------------+-----------------------------------------------------------+------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+----------+----------------------------------------+--------------------+-----------------------------------------------------------+------------+
| | POST | api/register | | App\Http\Controllers\AuthController@register | api |
+--------+----------+----------------------------------------+--------------------+-----------------------------------------------------------+------------+
请求使用insomnia:
我的 base_api 失眠值是 http://mylocal.app/api
错误信息:
Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException
错误显示信息:
路由器(api.php):
Route::post('register', 'AuthController@register');
控制器(AuthController.php):
use App\Http\Requests\StoreRegistration;
public function register(StoreRegistration $request)
{
$email = $request->email;
$name = $request->name;
$password = $request->password;
$user = User::create([
'name' => $name,
'email' => $email,
'password' => Hash::make($password)
]);
$verifyUser = VerifyUser::create([
'user_uuid' => $user->uuid,
'token' => str_random(100)
]);
SendVerificationEmail::dispatch($user); //I use queue to send email
return response()->json(['success' => true, 'message' => 'message on success']);
}
StoreRegistration.php :
class StoreRegistration extends FormRequest {
public function authorize()
{
return true;
}
public function rules()
{
return [
'name' => 'required|min:4|max:50|unique:users|alpha_dash',
'email' => 'email|required|max:255|unique:users',
'password' => 'required|confirmed|min:6'
];
}
}
这个问题让我抓狂。
错误不是来自验证。
这是因为当您使用 FormRequest class 时,您正在使用其默认的 failedValidation 方法,该方法适用于 web 和重定向到错误的上一页。在您的情况下,您正在使用 api 但它重定向到不存在的 url 。当您使用标准验证时,您就是在指定自己的逻辑。
throw new ValidationException($validator, $this->response(
$this->formatErrors($validator)
));
因此,您需要使用 api 自定义失败验证方法。您可以在 StoreRegistration class 中执行类似操作,您可以将 failedValidation 方法重写为以下 -
public $validator = null;
protected function failedValidation(\Illuminate\Contracts\Validation\Validator $validator)
{
$this->validator = $validator;
}
然后你的控制器方法,用你的 $validator 对象做任何你想做的事。可能像下面这样-
if (isset($request->validator) && $request->validator->fails()) {
return response()->json($request->validator->messages(), 400);
}
看看thislink我之前回答过的
当您从失眠发送请求时,请务必添加 headers;
接受:application/json
和 Content-Type: application/json
那样 laravel 知道它是一个 api 请求,并将使用在 api.php
而不是 web.php
上定义的路由。
这很奇怪,当我在 Laravel 5.5 上使用 Form Request Validation 时,我所有的 post 请求都将是 405 Method Not Allowed,但是当我使用标准验证时变得正常,这是我的代码是:
php artisan route:list 值
+--------+----------+----------------------------------------+--------------------+-----------------------------------------------------------+------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+----------+----------------------------------------+--------------------+-----------------------------------------------------------+------------+
| | POST | api/register | | App\Http\Controllers\AuthController@register | api |
+--------+----------+----------------------------------------+--------------------+-----------------------------------------------------------+------------+
请求使用insomnia:
我的 base_api 失眠值是 http://mylocal.app/api
错误信息:
Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException
错误显示信息:
路由器(api.php):
Route::post('register', 'AuthController@register');
控制器(AuthController.php):
use App\Http\Requests\StoreRegistration;
public function register(StoreRegistration $request)
{
$email = $request->email;
$name = $request->name;
$password = $request->password;
$user = User::create([
'name' => $name,
'email' => $email,
'password' => Hash::make($password)
]);
$verifyUser = VerifyUser::create([
'user_uuid' => $user->uuid,
'token' => str_random(100)
]);
SendVerificationEmail::dispatch($user); //I use queue to send email
return response()->json(['success' => true, 'message' => 'message on success']);
}
StoreRegistration.php :
class StoreRegistration extends FormRequest {
public function authorize()
{
return true;
}
public function rules()
{
return [
'name' => 'required|min:4|max:50|unique:users|alpha_dash',
'email' => 'email|required|max:255|unique:users',
'password' => 'required|confirmed|min:6'
];
}
}
这个问题让我抓狂。
错误不是来自验证。
这是因为当您使用 FormRequest class 时,您正在使用其默认的 failedValidation 方法,该方法适用于 web 和重定向到错误的上一页。在您的情况下,您正在使用 api 但它重定向到不存在的 url 。当您使用标准验证时,您就是在指定自己的逻辑。
throw new ValidationException($validator, $this->response(
$this->formatErrors($validator)
));
因此,您需要使用 api 自定义失败验证方法。您可以在 StoreRegistration class 中执行类似操作,您可以将 failedValidation 方法重写为以下 -
public $validator = null;
protected function failedValidation(\Illuminate\Contracts\Validation\Validator $validator)
{
$this->validator = $validator;
}
然后你的控制器方法,用你的 $validator 对象做任何你想做的事。可能像下面这样-
if (isset($request->validator) && $request->validator->fails()) {
return response()->json($request->validator->messages(), 400);
}
看看thislink我之前回答过的
当您从失眠发送请求时,请务必添加 headers;
接受:application/json
和 Content-Type: application/json
那样 laravel 知道它是一个 api 请求,并将使用在 api.php
而不是 web.php
上定义的路由。