V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
peizhao2017
V2EX  ›  问与答

nginx 可以直接做伪静态吗?

  •  
  •   peizhao2017 · 2018-05-10 20:55:54 +08:00 · 3897 次点击
    这是一个创建于 2371 天前的主题,其中的信息可能已经有所发展或是发生改变。
    nginx 可以直接做伪静态吗?
    就是通过正则直接把 abc.php?id=1234 转换成 /abc/1234/ 这种
    php 程序不做修改


    另外伪静态成 /abc/1234/ 这种目录形式
    还是 /abc/1234.html 这种形式比较好
    18 条回复    2018-05-18 09:55:29 +08:00
    Felldeadbird
        1
    Felldeadbird  
       2018-05-11 00:13:24 +08:00 via iPhone
    完全可以。规则和 apache 差不多,细节要处理一下。例如 apache 开头不用加 /,nginx 要。具体你上网搜索一下开源的程序,找一下对应 nginx 伪静态规则,自己在钻研一下就明白了
    peizhao2017
        2
    peizhao2017  
    OP
       2018-05-11 00:26:37 +08:00
    @Felldeadbird #1

    不是
    我的意思是在程序代码不变的情况下可以直接用 nginx 做伪静态吗

    比如 还让程序输出 abc.php?id=1234 这种链接

    nginx 直接转换成 /abc/1234/ 这种目录形式
    dobelee
        3
    dobelee  
       2018-05-11 00:30:34 +08:00 via Android
    正則替換了解一下。
    Felldeadbird
        4
    Felldeadbird  
       2018-05-11 00:37:56 +08:00 via iPhone
    @peizhao2017 我说的就是修改 nginx conf
    zgx030030
        5
    zgx030030  
       2018-05-11 00:41:06 +08:00 via iPhone
    搜了下,nginx 有替换响应内容的模块,没用过不了解,nginx 还是不适合做这个吧。。
    agagega
        6
    agagega  
       2018-05-11 00:54:15 +08:00
    @peizhao2017

    看上去,你的需求似乎有两个。一是把进来的请求从 a.php?id=1 转换成 a/1 ;二是把 PHP 程序里生成的形如 a.php?id=1 的链接转换回 a/1。

    在 Apache 里,第一个功能叫 mod_rewrite,第二个叫 mod_substitute。我对 Nginx 不是很熟,你可以用这两个关键字搜索一下,名字应该不差太多。
    msg7086
        7
    msg7086  
       2018-05-11 02:30:47 +08:00
    第一个要求是 rewrite,第二个要求是 substitute。
    Nginx 里 rewrite 和 sub_filter 都有。
    plko345
        8
    plko345  
       2018-05-11 06:34:13 +08:00 via Android
    @agagega 请问除了官方文档,有 apache 方面的书籍吗,比较好的那种,豆瓣搜到的似乎都不是特别好
    aiseo
        9
    aiseo  
       2018-05-11 08:37:38 +08:00
    歪个楼,请问 Apache 怎么实现楼主说的功能?
    aiseo
        10
    aiseo  
       2018-05-11 08:41:08 +08:00
    反向代理能实现替换吧?
    peizhao2017
        11
    peizhao2017  
    OP
       2018-05-11 09:37:39 +08:00
    @msg7086 #7
    尝试了下
    nginx 规则
    location / {
    rewrite ^/([0-9]+)/$ /forums.php?fid=$1 last;
    }


    程序端不修改输出的链接还保持原样的话
    www.abc.com/forums.php?fid=123
    这个规则无效


    如果改下代码
    把 php 输出的链接改为 www.abc.com/123/
    那么对应的 rewrite 的正常生效


    其实我想问的是
    怎样在不改程序输出的链接
    还保持 www.abc.com/forums.php?fid=123 这种格式

    直接用 nginx 完成伪静态?
    msg7086
        13
    msg7086  
       2018-05-11 09:46:31 +08:00
    如果你链接格式非常固定,也可以用 nginx 自己内置的 sub_filter。
    要用正则,需要用上面那个插件。
    peizhao2017
        14
    peizhao2017  
    OP
       2018-05-11 10:03:20 +08:00
    @msg7086 #13

    @agagega #6

    学习了下
    应该就是 sub_filter 这个模块
    但 sub_filter 不支持正则
    支持正则的是另外一个模块 subs_filter
    直接正则替换网页中的链接



    除了需要 nginx 安装 sub_filter 模块

    为什么大部分程序都是用 rewrite 配合程序设置来完成伪静态
    zgx030030
        15
    zgx030030  
       2018-05-11 10:11:22 +08:00
    你不用 web 服务器做 rewrite,像 www.do.com/abc/def.html 这样的 你来说说如何跳转到某个 php 中?
    msg7086
        16
    msg7086  
       2018-05-11 10:16:27 +08:00
    @peizhao2017 技术限制。
    地址重写通常是从简单地址转写到复杂的 args 地址,所以这步可以交由 Web Server 来负责。
    反过来 args 地址转写到简单地址通常在程序生成链接的时候就能做,先生成 args 地址再转写,相当于多此一举。

    至于 rewrite 为什么交给 Web Server 来做,那也是历史遗留问题,以前 PHP 的框架没有路由系统,路由大多是自己实现或者根本就不用,伪静态在世界上还没有搜索引擎的时候也并不重要。后期有了伪静态需求的时候,再追加一个路由系统进去就比较复杂,不如让 Web Server 来解决,程序里也只需要修改视图模板就行了。

    如果你看过一些非 PHP 的程序,比如 Python Rails 写的,又或者是比较现代化的 PHP 程序,就会知道,Web Server 根本不需要插手 rewrite,因为程序框架的路由器就能解析地址。nginx 里直接写 try_files $uri index.php; 就能跑了。
    peizhao2017
        17
    peizhao2017  
    OP
       2018-05-11 10:40:08 +08:00
    @msg7086 #16
    非常感谢
    完全明白了
    aiseo
        18
    aiseo  
       2018-05-18 09:55:29 +08:00
    @msg7086
    @peizhao2017

    感谢!我也有这种需求,目前是反代加 sub_filter 实现。有空再试试 subs_filter
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1085 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 19:12 · PVG 03:12 · LAX 11:12 · JFK 14:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.