后台把固定链接从“朴素”改成“文章名”,保存之后首页还能打开,点进任何一篇文章都是404,改回朴素又全部正常。多数人的第一反应是去看.htaccess,文件在,规则也在,内容一个字没写错。问题在于nginx根本不读这个文件,它只认配置文件里的location和rewrite,根目录那个.htaccess对nginx来说只是一个普通文件,留着不碍事,也不起任何作用。文件里那段重写规则看着很像生效了,实际一次都没被执行过。
Apache靠.htaccess做重写,nginx没有对应的机制,两者的配置思路完全不同。站点从虚拟主机搬到云服务器、或者从Apache换成nginx之后,固定链接会集体失效。首页能进,是因为它本来就指向真实文件。这不是配置漏了,是跑在下面的软件换了,重写逻辑得跟着一起搬。
补法是在server段里加一段location /,内容为try_files $uri $uri/ /index.php?$args;。含义是先找同名文件,再找同名目录,两者都不存在就把请求交给index.php,由WordPress自己解析路径。静态资源会在第一步被nginx直接返回,不经过PHP,这也是这套写法比全量转发快的原因。这一段要写在server块里,放进http块会报unknown directive,放错一层就全盘不生效。
末尾的?$args不能省。少了它,带查询字符串的地址在转发时参数会被丢掉,分类页翻页、搜索结果页这类靠参数区分内容的页面就会串到一起,症状是翻页永远停在第1页。搜索页的症状更明显,关键词传不过去,出来永远是全部文章。
加完没反应还有两种可能。一种是忘了reload,nginx -t通过只代表语法没错,进程没收到信号就还是老配置。另一种是这段location被别的块截走了,server里若另有一条location ~ \.php$或者更精确的location,nginx按前缀长度和正则优先级选取,写在文件后面的块不一定生效。用nginx -T能打出最终生效的完整配置,比翻源文件可靠,include进来的片段也一并列出来。查到被谁截走,就把try_files挪进那个块。
继续用Apache的话,要确认httpd.conf里对应目录的AllowOverride是All,否则.htaccess写什么都没用,默认模板里常常是None。这个选项通常被注释掉了,得手动打开,改完要重启httpd,reload不够。
curl -I打一篇文章的地址,返回200且内容长度正常就算通了,还是404说明规则没走到,回头核location的匹配顺序。顺手再打一条静态资源的地址,确认它没被转给PHP。
申请创业报道,分享创业好点子。点击此处,共同探讨创业新机遇!
