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

Laravel 10使用自定义验证请求类报错405方法不允许

Laravel API使用自定义FormRequest出现405 Method Not Allowed错误

使用VendorStoreRequest类对store方法的请求进行验证时,触发405 Method Not Allowed错误;但替换为原生的Illuminate\Http\Request则能正常运行。

报错代码示例

use App\Http\Requests\VendorAccount\VendorStoreRequest;
...
public function store(VendorStoreRequest $request)
{
    return response()->json($request, 200);
}

正常运行代码示例

use Illuminate\Http\Request;
...
public function store(Request $request)
{
    return response()->json($request, 200);
}

路由定义

当前使用API资源路由,代码如下:

Route::prefix('vendor')->group(function () {
    Route::apiResource('/', VendorController::class)->parameters(['' => 'vendor']);
});

VendorStoreRequest代码

<?php

namespace App\Http\Requests\VendorAccount;

use Illuminate\Foundation\Http\FormRequest;

class VendorStoreRequest 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 [
            'name' => 'required|min:5',
            'email' => 'required|unique:vendors|email',
            'phone' => 'required|digits:11|numeric|unique:vendors',
            'business_phone' => 'required|digits:11|numeric|unique:vendors',
            'password' => 'required|min:6',
            'business_name' => 'required|unique:vendors',
            'trade_licence_no' => 'required|regex:/^[0-9]+$/|max:20|unique:vendors',
            'bank_account_no' => 'required|regex:/^[0-9]+$/|max:20|unique:vendors',
            'nid' => 'required|digits_between:10,13|unique:vendors',
            'image' => 'required|image|mimes:jpg,png,jpeg'
        ];
    }

    public function messages()
    {
        return [
            'name.min' => 'Name should be at least 5 characters',
            'phone.digits' => 'Phone number is not valid',
            'phone.unique' => 'Phone number has already been taken',
            'business_phone.digits' => 'Business phone number is not valid',
            'business_phone.unique' => 'Business phone number has already been taken',
            'password.min' => 'Password should be at least 6 characters',
            'business_name.unique' => 'Business name has already been taken',
            'trade_licence_no.regex' => 'Trade licence number is not valid',
            'trade_licence_no.unique' => 'Trade licence number is duplicate',
            'bank_account_no.regex' => 'Bank account number is not valid',
            'bank_account_no.unique' => 'Bank account number is duplicate',
            'nid.digits_between' => 'NID number is not valid',
            'nid.unique' => 'NID number is duplicate',
            'nid.digits_between' => 'NID number is not valid',
        ];
    }
}

问题原因

核心问题出在API资源路由的定义上:使用空字符串作为apiResource的资源名称,再配合parameters(['' => 'vendor'])的写法,会导致Laravel生成的路由规则出现异常。当使用自定义FormRequest时,Laravel的请求验证流程会先对请求进行路由匹配检查,异常的路由规则会让系统误判请求方法不被允许,从而返回405错误。而原生Request不会触发这一层严格的路由匹配校验,所以能正常运行。

解决方案

修改路由定义,避免使用空字符串作为资源名称,推荐两种写法:

写法一:直接定义apiResource(无需prefix)

Route::apiResource('vendor', VendorController::class);

这样会生成标准的API路由:

  • POST /vendor(store方法)
  • GET /vendor(index方法)
  • GET /vendor/{vendor}(show方法)等

写法二:保留prefix,调整apiResource参数

如果需要保留prefix('vendor'),可以将资源名称改为非空值,比如vendors:

Route::prefix('vendor')->group(function () {
    Route::apiResource('vendors', VendorController::class)->parameters(['vendors' => 'vendor']);
});

此时生成的POST路由为/vendor/vendors,根据实际业务需求选择即可。

另外,需验证请求方法是否为POST,确保前端请求的方法与路由定义一致。

内容的提问来源于stack exchange,提问作者Wahidul Alam

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 09:57:53