ThinkPHP如何实现跨域资源共享配置_自定义CORS中间件开发

lianpo lianpo 关注 普通 入门站长
发表于编程技术版块

ThinkPHP如何实现跨域资源共享配置_自定义CORS中间件开发

ThinkPHP 6 需手写 CorsMiddleware 并在路由前执行,否则无效;必须处理 OPTIONS 预检、禁用 method_filter 或放行 OPTIONS、Access-Control-Allow-Origin 不能为 *(启 credentials 时)、Nginx 需透传或直接添加 CORS 头。

thinkphp如何实现跨域资源共享配置_自定义cors中间件开发

ThinkPHP 6 的 CorsMiddleware 怎么写才生效

直接给结论:ThinkPHP 6 默认不带跨域(https://www.php.cn/zt/20277.html)中间件,必须手写一个,并确保它在路由匹配前执行。很多人写了中间件但没生效,根本原因是注册位置不对或响应头被后续逻辑覆盖。

实操要点:

  • 中间件类需继承 think\Middlewarehandle() 方法里手动设置响应头
  • 必须在 app/middleware.php 中全局注册,或在 route/app.php 里用 ->middleware() 显式挂载到对应路由组
  • 注意顺序:如果用了 AllowCrossDomain 类似命名的中间件,但后面又跑了 ValidateToken 或自定义异常处理,它们可能重置响应头
  • 示例关键代码:复制AI写代码

    public function handle($request, \Closure $next)<br>{<br>    $response = $next($request);<br>    $response->header('Access-Control-Allow-Origin', '*');<br>    $response->header('Access-Control-Allow-Methods', 'GET,POST,OPTIONS,DELETE,PUT');<br>    $response->header('Access-Control-Allow-Headers', 'Content-Type,Authorization,X-Requested-With');<br>    $response->header('Access-Control-Allow-Credentials', 'true');<br>    return $response;<br>}

为什么 OPTIONS 预检请求总返回 405 或空白响应

这是最常踩的坑:ThinkPHP 默认把 OPTIONS 当作非法方法拦截了,尤其在开启 method_filter 或使用了资源路由时。

解决路径很明确:

立即学习“PHP免费学习笔记(深入)(https://pan.quark.cn/s/7fc7563c4182)”;

  • 在中间件 handle() 开头加判断:if ($request->isOptions()) { return response('', 200)->header([...]); }
  • 确保 app/config/app.php 中 'method_filter' => false,或至少把 OPTIONS 加进白名单数组
  • 别依赖前端发 Content-Type: application/json 就自动触发预检——只要带了 AuthorizationX-Requested-With 或自定义 header,浏览器一定发 OPTIONS
  • 调试时用 curl -X OPTIONS -I http://your-api.com/xxx 看真实响应头,别只信浏览器 Network 面板

 Access-Control-Allow-Credentials 设为 true 后跨域请求仍失败

设了 true 却拿不到 cookie 或 token,大概率是前端没配 + 后端没配全。

PHP 8.5.5(https://www.php.cn/xiazai/gongju/2229)

PHP 8.5.5(https://www.php.cn/xiazai/gongju/2229)

PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。

下载(https://www.php.cn/xiazai/gongju/2229)

两端必须同步满足:

  • 后端响应头除了 Access-Control-Allow-Credentials: trueAccess-Control-Allow-Origin **不能是 ***,得写具体域名,比如 https://admin.example.com
  • 前端 fetch 或 axios 请求必须显式加 credentials: 'include'(Vue Axios 示例:axios.get('/api/user', { withCredentials: true })
  • ThinkPHP 的 session 配置要兼容:确认 app/session.php 中 'domain' => '.example.com'(注意开头的点),且 cookie 的 SameSite 值设为 Lax 或 None(后者需同时配 Secure

生产环境 Nginx 反代下 CORS 头消失的排查点

本地测试好好的,一上 Nginx 就跨域失败,90% 是反代配置吞掉了响应头。

重点检查这几处:

  • Nginx 配置里有没有 proxy_hide_header 或 fastcgi_hide_header 误删了 Access-Control-* 头
  • 是否用了 proxy_pass_request_headers off 这类非常规设置
  • 确认 PHP-FPM 的 fastcgi_param 没过滤 header(虽然少见,但某些安全加固模板会加)
  • 更简单粗暴的办法:在 Nginx 层直接加头,比如 add_header 'Access-Control-Allow-Origin' 'https://admin.example.com' always;,但要注意 always 参数,否则 4xx/5xx 响应不生效

跨域不是“加几个 header 就完事”的事,它是客户端、应用层、反代层三者共同协商的结果。少一个环节对不上,就卡在预检或凭据传递上。尤其是 Origin 值的动态校验和 credentials 的严格配对,最容易被当成小问题忽略掉。

评论列表 评论
发布评论

评论: ThinkPHP如何实现跨域资源共享配置_自定义CORS中间件开发

已有0次打赏
(0) 分享
分享

请保存二维码或复制链接进行分享

取消