thinkphp中间件中options预检请求返回405,是因为框架默认不处理options方法,尤其开启method_filter或使用资源路由时会直接拦截并抛出405;必须在中间件handle()开头添加短路逻辑:if ($request->isoptions()) { return response('', 204); },禁用method_filter或将其加入白名单,并确保cors中间件注册于全局中间件数组首位且nginx透传origin头并正确设置always参数。

ThinkPHP中间件里OPTIONS预检请求为什么总返回405
因为ThinkPHP默认把OPTIONS当作非法方法拦截,尤其在开启method_filter或用了资源路由时。不主动响应,框架就直接抛405。
必须在中间件handle()开头加短路逻辑:
if ($request->isOptions()) {
return response('', 204);
}
-
204比200更规范,避免代理或CDN对空响应体做额外处理 - 别写
return $next($request)——走了路由匹配,大概率触发405 - 确保
app/config/app.php中'method_filter' => false,或至少把OPTIONS加进白名单数组
Access-Control-Allow-Origin设为*却带credentials:true时失败
浏览器会直接拒绝请求,不是后端没发头,而是策略层面禁止——Access-Control-Allow-Origin: *和Access-Control-Allow-Credentials: true互斥。
前后端必须同步改:
- 后端不能硬编码
*,得动态校验$request->header('Origin')是否在白名单,再回写对应值,例如https://admin.example.com - 前端fetch必须配
credentials: 'include',jQuery需加xhrFields: { withCredentials: true } - 如果用session,还要在
config/session.php里设'domain' => '.example.com'(注意开头的点)
自定义CorsMiddleware注册后为什么没生效
中间件写了但没跑,90%是注册位置或执行顺序错了。ThinkPHP 6 不自动执行任何CORS中间件,必须手动挂载且优先级足够高。
关键操作只有两步:
- 在
app/middleware.php的全局中间件数组里,把\app\middleware\CorsMiddleware::class放在**首位**——确保它最先执行、最后结束,不被后续中间件覆盖头信息 - 别依赖
route/app.php里的->middleware()链式调用——那只是局部绑定,对全局API无效 - 如果用了多应用模式,确认中间件注册到了当前应用,不是只写在全局
middleware.php里就完事
Nginx反向代理下CORS头为什么被吞掉
TP6发出了头,但浏览器收不到,常见于Nginx → Swoole或Nginx → PHP-FPM架构。Nginx默认不透传Origin头,也不转发自定义响应头。
必须在Nginx配置里显式声明:
proxy_set_header Origin $http_origin; add_header 'Access-Control-Allow-Origin' '$http_origin' always; add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always; add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, X-Requested-With' always; add_header 'Access-Control-Allow-Credentials' 'true' always;
-
always参数很重要,否则Nginx可能跳过对2xx以外状态码的头设置 - 别同时在PHP和Nginx里设
Access-Control-Allow-Origin——冲突会报CORS header ‘Access-Control-Allow-Origin’ cannot be used with wildcard - 调试时用
curl -X OPTIONS -I http://your-api.com/xxx看真实响应头,绕过浏览器缓存干扰
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











