DELETE请求405错误是ThinkPHP路由未注册对应DELETE方法,需显式使用Route::delete()或->method('DELETE')声明,否则路由阶段即拒绝,控制器不会执行。

DELETE 请求 405 Method Not Allowed 是路由没注册对应方法
ThinkPHP 默认不接受 DELETE 方法的请求,除非你显式注册了 Route::delete() 或用 ->method('DELETE') 约束。浏览器地址栏直接输 URL 默认是 GET,但真正触发 DELETE 的通常是 AJAX 或表单(需配合 _method=DELETE 模拟),而框架在路由阶段就拒绝了——根本不会进控制器。
常见错误现象:前端发 DELETE /api/user/123,返回 HTTP 405,控制台能看到响应头 Allow: GET, POST,但控制器里的 delete() 方法压根没执行。
- 检查路由定义是否用了
Route::delete('api/user/:id', 'Api/User.delete'),而不是Route::get()或裸Route::rule() - 如果用
Route::rule(),必须加->method('DELETE'),例如:Route::rule('api/user/:id', 'Api/User.delete')->method('DELETE') - 别指望
Route::any()自动覆盖 DELETE —— 它默认只支持['GET', 'POST', 'HEAD', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],但必须显式声明:->method(['GET', 'DELETE']) - 确认请求头
Content-Type是application/json或application/x-www-form-urlencoded,否则某些中间件可能提前拦截
用了 RESTful 资源路由但 DELETE 不生效
Route::resource('user', 'User') 确实会自动生成 DELETE 路由,但它绑定的是 destroy 方法,路径是 /user/:id(不是 /user/:id/delete),且仅响应 DELETE 方法。很多人写错路径或方法名,导致匹配失败。
- 生成的 DELETE 路由规则是:
DELETE /user/:id → User.destroy,不是User.delete;类里必须有public function destroy($id) { ... } - 如果想用
/user/:id/delete这种路径,不能依赖Route::resource(),得单独补一条:Route::delete('user/:id/delete', 'User.delete') -
Route::resource()不支持为单个动作改方法,比如不能让destroy同时响应 PUT 和 DELETE —— 必须额外注册:Route::put('user/:id', 'User.destroy')->middleware('auth') - 注意大小写:Linux 下
User.php和user.php是两个文件,类名也必须是User,不是user或UserController
伪静态或服务器配置导致 DELETE 被丢弃
Nginx/Apache 默认可能过滤掉非标准方法,尤其当用 index.php?s=... 模式访问时,s 参数无法携带方法信息,DELETE 就被降级成 GET。
立即学习“PHP免费学习笔记(深入)”;
- 确保入口 URL 是标准格式,如
/api/user/123,而不是/index.php?s=/api/user/123 - Nginx 配置中,
try_files或rewrite规则必须透传原始请求方法,不能强制转成 GET:if (!-e $request_filename) { rewrite ^(.*)$ /index.php?s=$1 last; }❌(丢方法)try_files $uri $uri/ /index.php?$query_string;✅(保方法) - Apache 的
.htaccess要启用mod_rewrite,且规则末尾带[QSA,L]保留查询参数和方法 - 用
php think route:list查看实际注册的路由,确认Method列包含DELETE,且Rule路径与请求完全一致(含斜杠、变量占位符)
CSRF 或中间件提前终止 DELETE 请求
ThinkPHP 默认开启 CSRF 防护,而 DELETE 请求若没带有效 token,会在路由匹配前就被中间件拒绝,表现为 405 或 403,但日志里可能只显示“token mismatch”。
- 检查
app/middleware.php是否把VerifyToken放在了路由之前;如果是,需排除 API 路径:['except' => ['api/*']] - API 接口建议关掉 CSRF:
config/middleware.php中移除think\middleware\ValidateToken,或在路由分组里禁用:Route::group('api', function () { ... })->middleware([]) - 自定义中间件里用了
$this->request->isDelete()但没放行,也会卡住;确认中间件最后调用了$next($request) - 测试时先临时关闭所有中间件,确认 DELETE 路由本身能通,再逐个加回
php think route:list | grep DELETE,一眼看出有没有注册、路径对不对、方法是不是全大写。很多问题根本不在代码逻辑,而在那条没写上的 Route::delete()。



















