ThinkPHP 6 默认 CORS 中间件硬编码限制仅允许 GET、HEAD、POST,需自定义 FullCors 中间件扩展支持 PUT/DELETE,并显式配置 Access-Control-Allow-Methods、Origin(非*)、Credentials 和 Headers 才能正确处理带凭据的跨域请求。

ThinkPHP 6 如何正确配置 PUT/DELETE 跨域请求
默认情况下,ThinkPHP 6 的 CORS 中间件不自动放行 PUT 和 DELETE 方法,即使你写了 Access-Control-Allow-Methods: *,浏览器预检(preflight)仍可能失败——因为中间件内部做了硬编码白名单过滤。
为什么 Access-Control-Allow-Methods: * 在 ThinkPHP 6 里不生效
ThinkPHP 6 的 think\middleware\Cors 中间件在处理预检请求时,会显式校验 Access-Control-Request-Method 是否在内置白名单中,默认只包含 GET、HEAD、POST。哪怕你配置了通配符,它也会跳过匹配逻辑直接拒绝 PUT 或 DELETE。
- 源码位置在
think\middleware\Cors::handle()方法内,关键判断是in_array($method, ['GET', 'HEAD', 'POST']) - 该白名单不可通过配置项覆盖,必须手动扩展或替换中间件
- 注意:这个限制只影响预检请求(OPTIONS),不影响实际的 PUT/DELETE 请求本身
实操:自定义 Cors 中间件并注册
最稳妥的方式是复制原中间件逻辑,把允许方法列表补全。不要试图用配置“绕过”,那没用。
- 新建文件
app/middleware/FullCors.php,继承think\middleware\Cors - 重写
handle()方法,在校验$method前插入完整方法数组:['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'OPTIONS'] - 在
app/middleware.php中注册该中间件,**放在路由中间件之前**(否则可能被跳过) - 确保响应头中
Access-Control-Allow-Methods显式写出全部方法,不要用*(某些浏览器对带凭据的请求不认*)
return [
\app\middleware\FullCors::class,
];
容易踩的坑:CORS + Cookie / Authorization 请求
如果你的 PUT/DELETE 请求带 withCredentials(如前端设了 credentials: 'include'),后端必须同时满足三个条件,缺一不可:
立即学习“PHP免费学习笔记(深入)”;
-
Access-Control-Allow-Origin不能为*,必须是具体域名,例如https://example.com -
Access-Control-Allow-Credentials必须设为true(且中间件里要显式输出) -
Access-Control-Allow-Headers必须包含你实际发送的字段,比如Authorization、X-Requested-With等 - 注意:ThinkPHP 默认中间件不会自动回传客户端发来的
Origin,需要手动透传,否则跨域凭据失效
复杂点在于,这些头不是独立生效的——漏掉任意一个,浏览器就静默失败,控制台可能只显示 “CORS error”,连 OPTIONS 响应都看不到。



















