·设为首页收藏本站📧邮箱修改🎁免费下载专区📒收藏夹📱AI全功能
返回列表 发布新帖

Z-BlogPHP伪静态规则避坑

112 1
发表于 2026-2-10 15:26:54 | 查看全部 阅读模式

马上注册,免费下载更多dz插件网资源。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
Z-BlogPHP伪静态规则避坑 单页,location,if,rewrite,api

不知道你们有没有注意到下面的一排红字,正确写法
  1. location / {    if (-f $request_filename/index.html) {    rewrite (.*) $1/index.html break;    }    if (-f $request_filename/index.php) {    rewrite (.*) $1/index.php;    }    if (!-f $request_filename) {    rewrite (.*) /index.php;    }}
复制代码


配置ngx_cache_purge一直报错404,太坑了。


一、核心区别详解
首先先明确两段配置的共同目标:访问目录时优先匹配 index.html,其次匹配 index.php;如果请求的不是实际存在的文件,则转发到 /index.php(通常用于 PHP 单页应用路由)。但两者的执行逻辑和生效范围有本质区别:

1. 作用域(最核心区别)
    第一段配置:if 指令直接写在 server 块内(非 location 块中),属于server 级全局指令。
这意味着这些 if 判断会作用于所有匹配该 server 的请求—— 无论请求是 /、/api/、/admin/ 还是其他路径,只要没有被更严格的 location 显式拦截,都会先执行这些 if 逻辑。
例如:请求 /api/test 时,即使有 location /api {} 配置,也会先执行这些全局 if 判断,可能导致非预期的 rewrite。
第二段配置:if 指令被包裹在 location / {} 块内,属于location 级局部指令。
仅作用于匹配 location / 的请求(location / 是 Nginx 最宽泛的匹配规则,只有当请求没有被更具体的 location 如 location /api、location ^~ /admin 匹配时,才会进入这个块执行 if 逻辑)。
    例如:请求 /api/test 若匹配 location /api {},则完全不会执行 location / 内的这些 if,仅对无专属 location 的请求生效。

2. 执行时机
Nginx 配置的执行顺序是:server 级指令 → 匹配 location → 执行 location 内指令。
    第一段配置:server 级的 if 在location 匹配之前执行,相当于 “全局前置拦截”,可能覆盖后续 location 的配置逻辑。
    第二段配置:location / 内的 if 在location 匹配完成后执行,逻辑更可控,仅影响当前 location 内的请求处理。

3. Nginx 配置规范(安全性 / 最佳实践)
Nginx 官方明确指出 if 是 “邪恶的 if”(Evil If),强烈不建议在 server 级直接使用 if 处理 rewrite:
    第一段配置:server 级 if 容易和后续 location 内的 rewrite、proxy 等指令冲突,导致非预期的跳转(比如 /api/ 路径被错误转发到 /index.php)。
    第二段配置:if 局限在 location / 内,仅处理最宽泛的根路径请求,冲突风险极低,符合 Nginx 最佳实践。

4. break 指令的行为差异
第一段和第二段的第一个 if 都有 break,第二个 if 没有,但因作用域不同,break 的效果也不同:
    server 级的 break:终止所有后续的 rewrite/if 处理(包括后续 location 内的指令);
    location 内的 break:仅终止当前 location 内的 rewrite/if 处理,不会影响其他 location 的执行,更安全。

二、示例对比(直观理解)
当请求 example.com/api/test 时:
        若用第一段配置:会先执行全局 if,如果 $request_filename 不是文件,会被强制 rewrite 到 /index.php,覆盖 location /api/ 的 proxy 逻辑(非预期);
        若用第二段配置:/api/test 匹配 location /api/,不会进入 location /,因此不会执行里面的 if,proxy_pass 逻辑正常生效(符合预期)。

三、总结
    核心区别是作用域:第一段是 server 级全局生效(所有请求),第二段仅对 location / 匹配的请求生效(无专属 location 的根路径请求)。
    执行时机不同:server 级 if 在 location 匹配前执行(易冲突),location 内 if 在匹配后执行(更可控)。
    配置规范:第二段(location 内写 if)是 Nginx 推荐的写法,避免全局 rewrite 导致的非预期冲突,安全性更高。
我要说一句 收起回复

评论1

独家记忆Lv.8 发表于 2026-2-10 15:27:02 | 查看全部
又见判断。。。
我要说一句 收起回复
回复 支持 反对

使用道具 举报

回复

 懒得打字嘛,点击右侧快捷回复【查看最新发布】   【应用商城享更多资源】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

图文热点
关闭

站长推荐上一条 /1 下一条

最新热评 加载中...
AI智能体
投诉/建议联系

discuzaddons@vip.qq.com

未经授权禁止转载,复制和建立镜像,
如有违反,按照公告处理!!!
  • 联系QQ客服
  • 添加微信客服

联系DZ插件网微信客服|最近更新|Archiver|手机版|小黑屋|DZ插件网! ( 鄂ICP备20010621号-1 )|网站地图 知道创宇云防御

您的IP:216.73.216.99,GMT+8, 2026-2-23 19:26 , Processed in 1.850988 second(s), 79 queries , Gzip On, Redis On.

Powered by Discuz! X5.1 Licensed

© 2001-2026 Discuz! Team.

关灯 在本版发帖
扫一扫添加微信客服
QQ客服返回顶部
快速回复 返回顶部 返回列表