伪静态与跨域配置在ThinkPHP5中需协同生效:伪静态必须正确传递PATH_INFO并指向public/index.php,跨域中间件须在路由解析后、响应前用$response->header()设置头,且Nginx禁用add_header避免冲突,同时拦截OPTIONS返回204。

伪静态和跨域配置在 ThinkPHP5 中不是互斥的,但容易因执行顺序、响应头注入时机或服务器层干预而冲突——最常见现象是:伪静态能访问接口,但跨域请求失败;或者 OPTIONS 预检 204 返回了,正式请求却 404 或 header 丢失。
伪静态规则必须指向 public/index.php,且 PATH_INFO 要完整传递
TP5 依赖 $_SERVER['PATH_INFO'] 解析路由,伪静态本质是把 /user/list 映射成 index.php?/user/list。如果 Nginx/Apache 没传 PATH_INFO,框架连路由都匹配不上,更别说执行中间件加跨域头了。
- Apache 下确保
.htaccess在public/目录,且规则末尾是index.php?/$1(注意问号),不是index.php/$1 - Nginx 必须在
location ~ \.php$块里显式补全:fastcgi_param PATH_INFO $fastcgi_path_info; - 宝塔用户务必检查「网站设置 → 运行目录」是否为
/public,否则$_SERVER['DOCUMENT_ROOT']错位,runtime/写入失败会导致中间件加载异常
跨域中间件必须在伪静态路由解析之后、响应输出之前生效
如果你用的是自定义中间件(比如 CorsMiddleware),它得在框架完成 URL 解析、匹配到控制器方法后才执行;否则 $request->isOptions() 可能判错,或 header 被后续逻辑覆盖。
- 中间件类中不要用
header()函数直接输出,改用$response->header(),确保头写入响应对象而非直接刷到输出缓冲 - 注册位置很重要:在
app/middleware.php中,CorsMiddleware应放在数组最前面,但它仍晚于路由解析——这是 TP5 的执行顺序决定的,无需调整 - 避免在
public/index.php里手动header(),否则和中间件重复设置会触发「Multiple Values」警告,Chrome 会静默拒绝响应
OPTIONS 预检必须被正确拦截,不能落到框架 404
伪静态开启后,浏览器发的 OPTIONS /api/user 请求,需要被准确识别为预检并快速返回 204。如果 Nginx 把它当普通请求转发给 PHP,而该路径又没定义对应路由,TP5 就会返回 404,跨域直接失败。
立即学习“PHP免费学习笔记(深入)”;
- 中间件里必须有
if ($request->isOptions()) { return response('', 204); },且放在$next($request)之前 - Nginx 层不要同时配
add_header Access-Control-Allow-Origin,否则和 PHP 层冲突;推荐完全交给中间件处理,删掉 server 块里所有add_header Access-Control-行 - 确认
try_files $uri $uri/ /public/index.php?$query_string;这条规则在location /里,它能兜住所有非静态资源请求,包括 OPTIONS
真正容易被忽略的点是:伪静态生效 ≠ 路由能跑通,跨域生效 ≠ 所有请求头都被透传。PATH_INFO 缺失、运行目录错位、中间件 header 写法不当、Nginx 和 PHP 层 CORS 头混用——这四个地方只要一个出问题,就会表现为“明明配了却跨不过去”。



















