Laravel 5.2:POST请求始终返回“405方法不允许”

14

我正在使用Laravel 5.2开发一个API,并遇到了一个重要问题。

我有一个UserController,将管理我的应用程序用户。

这是我的routes.php文件:

Route::group(array('prefix' => 'api/v1'), function() {    
   Route::post('user', 'UserController@store');
});

我有一个像这样定义的UserController:

class UserController extends Controller {

   public function index() {
       return 'Hello, API';
   }

   public function create(){
   }

   public function store(Request $request) {
       $user = new User;
       $user->email = $request->email;
       $user->password = $request->password;
       $user->fbId = $request->fbId;
       $user->ggId = $request->ggId;
       $user->firstName = $request->firstName;
       $user->lastName = $request->lastName;
       $user->imageUrl = $request->imageUrl;
       $user->country = $request->country;
       $user->mobile = $request->mobile;
       $user->gender = $request->gender;
       $user->client = $request->client;

       $user->save();

       return Response::json(array(
           'error' => false,
           'userId' => $user->id),
           200
       );
   }

   public function update(Request $request, $id) {
   }
}

这是 php artisan route:list 的输出结果

+--------+--------+-------------+------+-------------------------------------------+------------+
| Domain | Method | URI         | Name | Action                                    | Middleware |
+--------+--------+-------------+------+-------------------------------------------+------------+
|        | POST   | api/v1/user |      | App\Http\Controllers\UserController@store | web        |
+--------+--------+-------------+------+-------------------------------------------+------------+

我正在使用Postman测试我的POST请求。每次我向/api/v1/user发送POST请求,都会收到“405 Method Not Allowed”错误。

我有什么遗漏吗?是否应该采取措施解决这个问题?


@Kisaragi - 如果我使用 Route::post('user', 'UserController@store'),我会得到“405方法不允许”的错误。 - Joseph El Khoury
每次都调用索引方法。请只注释一次索引方法并查看结果。也许它会起作用! - Hiren Gohel
@GONG - 我试过了,但是没成功 :( - Joseph El Khoury
1
你能否尝试在组上移除你的“before”过滤器,只是为了看看它是否有效?我假设当你从Postman来时没有得到授权。 - patricus
@patricus - 我已经这么做了,但我仍然面临着同样的问题。最终我使用了 Route::post('user','UserController@store'),但是现在我总是收到“方法不允许”的错误提示。 - Joseph El Khoury
显示剩余11条评论
11个回答

47

我和你遇到了相同的问题,我已经在我的POST路由中设置了"/api/v1/user",

但是当我试图使用POSTMAN(用于测试API的应用程序)连接时,它会返回405-方法不允许。

然后我意识到我发送的URL正在使用'http',我将其更改为'https'(在末尾加上's')
然后我的API正常工作!

通常,如果我们与不同的服务器交互,我们必须使用'https',但如果您的应用程序在同一台服务器上,则可以使用'http'。

我这种情况的真正原因是与任何不同服务器的交互都必须使用'https'(这是我服务器的设置)。


天哪...谢谢你。这么简单的事情让我浪费了一个小时。 - z0mbieKale
哥们,你真是个英雄!浪费了这么多时间却一无所获!在curl中它运行得很好,因为CURLOPT_FOLLOWLOCATION=true。但在Postman中完全忘记了! - Ali Alwash
我刚刚意识到我在服务器上使用了SSL,浪费了两天时间。我真是太蠢了哈哈哈。 - NoobnSad

8
你需要分离你的路由,因为所有试图访问你的路由的用户都需要一个开放的会话(已登录)。
尝试这样做:
Route::group(array('prefix' => 'api/v1'), function() {

    Route::post('/','UserController@store');

    Route::get('/', 'UserController@index');

    Route::group(array('before' => 'auth.basic'), function() {

        Route::post('{user}', 'UserController@update');

    });
});

您的已授权用户路由应该在第二个组中。

而你的405方法不允许是$user->id,请将其更改为$request->user()->id


是的,你说得完全正确,但我刚开始这个项目,还没有将需要身份验证的端点与不需要身份验证的端点分开。 - Joseph El Khoury
你可能想要开始使用中间件 Route::group(['middleware' => 'auth'], function () { ... }); - Enmy Pérez Moncada
我会的 :) 谢谢 - Joseph El Khoury
@JosephELKHOURY 405方法不允许,将$user->id更改为$request->user()->id - Enmy Pérez Moncada
@JosephELKHOURY 记得保存 $user->save() - Enmy Pérez Moncada
@JosephELKHOURY 你写了你使用的命名空间吗?像 use App\User;use Illuminate\Http\Request; - Enmy Pérez Moncada

5

缺少CSRF令牌

我在创建“web-hooks”路由时,在Laravel 5.8上遇到了同样的问题。

这些路由使用网页中间件,因此包含VerifyCsrfToken路由中间件组。(参考app/Http/Kernel.php

由于我的POST请求不包括CSRF令牌,所以我们得到了这种奇怪的行为。

添加CSRF例外

为了解决这个问题,我需要为web-hooks路由添加一个VerifyCsrfToken中间件的例外。(参考app/Http/Middleware/VerifyCsrfToken.php)

/**
 * The URIs that should be excluded from CSRF verification.
 *
 * @var array
 */
protected $except = [
    'web-hooks/*'
];

使用API中间件

上述解决方案适用于使用Web中间件的情况。但是,如果您正在创建API路由,则最好使用api中间件,因为此中间件不使用CSRF验证。(参考app/Providers/RouteServiceProvider.php)

    Route::prefix('api')
        ->middleware('api')
        ->namespace($this->namespace)
        ->group(base_path('routes/api.php'));

3

更改为https将使其正常工作。至少,这是我的经验。使用POSTman进行http请求总是有这种影响。


0

请检查您的请求类型GET/POST/PUT/PATCH,无论是在前端(Javascript/Typescript等...)还是在后端(Laravel Passport),它都应该是相同的。


0

之前遇到过类似的问题,调试后发现是Postman的问题,与代码无关!

因此,请打开终端并尝试使用curl进行相同的请求:

curl -X POST -H "Accept: application/json" -F "email=test@test.com" -F "password=secret" -F "firstName=Mahmoud"  -F "lastName=Zalt" ....... "http://your-domain.com/api/v1/user"

如果这个方法可行,那么你需要在Postman中更改一些设置。 我真的不记得我具体做了什么!但是它只是像更改一些默认标头或删除授权类型这样简单的事情...


尝试检查您的HTTP中间件或启用CORS。 - Mahmoud Zalt

0
请确保您的头部信息中包含 "Accept":"application/json"。
例如: Accept: application/json User-Agent: Thunder Client (https://www.thunderclient.io) Content-Type: application/x-www-form-urlencoded

0
在我的情况下,我没有将“Controller”一词添加到控制器的名称中。

0

这个错误也可能是由于请求体过大引起的。在我的情况下,我不小心发送了一个包含许多子对象的对象,而这些子对象又都有许多其他的子对象。修剪我的请求数据解决了这个问题。


0

如果有帮助的话,我遇到了完全相同的问题;出于某种原因,一些组合的解决方案让它得以修复。

  1. 显而易见的是,它会返回一个 NotFoundHttpException in RouteCollection.php line 161,这是因为我在我的post请求中没有发送我的“api_token”。
  2. 由于某种原因(我不知道这是否有所不同),但是链接我的中间件起作用了,而不是将其放在Route:group中,我做了以下操作;

    Route::group(['prefix'=>'api/v1'], function () {
        Route::post('/', 'IndexController@index')->middleware('auth:api');
    });
    

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接