Apache2 mod_rewrite 因不存在的子目录而失败

Apache2 mod_rewrite 因不存在的子目录而失败

我的 .htaccess 文件的一个更短版本(没有 Last RewriteCond)在我的共享网络托管上可以完美运行,但我已经转移到带有 Ubuntu 12 及其原版 Apache2 的 VPS,但它根本不起作用(即使我进行了更改),我不知道为什么。我可以访问 example.com 或 example.com/news,但不能访问 example.com/article/4

我已经将 mod_rewrite 块从 .htaccess 放入 vhost 配置中,反之亦然,但似乎不起作用。我猜它实际上试图转到 article 子目录或类似的东西(不存在,因此 404),但我不知道如何阻止它这样做。

我正在使用 Apache 版本 2.2.22

我的虚拟主机文件

<VirtualHost 127.0.0.1:80>
DocumentRoot /home/example/www/example.com
RewriteLogLevel 3
RewriteLog /home/example/www/example.rewrite.log
<Directory "/home/example/www/example.com">
AllowOverride All
Options -ExecCGI +FollowSymLinks -Indexes -MultiViews
Order deny,allow
allow from all
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteOptions inherit
</IfModule>
</Directory>
AccessFileName .htaccess
ServerSignature Off
ServerName example.com
ErrorLog /home/example/www/example.log
LogLevel warn
</VirtualHost>

我的 .htaccess 文件

ErrorDocument 404 /index.php?404
ErrorDocument 403 /index.php?403
ErrorDocument 500 /index.php?500

Options -ExecCGI +FollowSymLinks -Indexes -MultiViews

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteOptions inherit

    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-s
    RewriteCond %{REQUEST_FILENAME} !-l
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_URI} !^/index\.php
    RewriteRule ^(.*)$ /index.php?$1 [L]
</IfModule>

访问 example.com/article/4 时重写重定向循环日志

[example.com/sid#8475130][rid#867d470/initial] (3) [perdir /home/example/www/example.com/] add path info postfix: /home/example/www/example.com/article -> /home/example/www/example.com/article/4
[example.com/sid#8475130][rid#867d470/initial] (3) [perdir /home/example/www/example.com/] strip per-dir prefix: /home/example/www/example.com/article/4 -> article/4
[example.com/sid#8475130][rid#867d470/initial] (3) [perdir /home/example/www/example.com/] applying pattern '^(.*)$' to uri 'article/4'
[example.com/sid#8475130][rid#867d470/initial] (2) [perdir /home/example/www/example.com/] rewrite 'article/4' -> '/index.php?article/4'
[example.com/sid#8475130][rid#867d470/initial] (3) split uri=/index.php?article/4 -> uri=/index.php, args=article/4
[example.com/sid#8475130][rid#867d470/initial] (2) [perdir /home/example/www/example.com/] trying to replace prefix /home/example/www/example.com/ with /
[example.com/sid#8475130][rid#867d470/initial] (1) [perdir /home/example/www/example.com/] internal redirect with /index.php [INTERNAL REDIRECT]
[example.com/sid#8475130][rid#b6ce9950/initial/redir#1] (3) [perdir /home/example/www/example.com/] strip per-dir prefix: /home/example/www/example.com/index.php -> index.php
[example.com/sid#8475130][rid#b6ce9950/initial/redir#1] (3) [perdir /home/example/www/example.com/] applying pattern '^(.*)$' to uri 'index.php'
[example.com/sid#8475130][rid#b6ce9950/initial/redir#1] (1) [perdir /home/example/www/example.com/] pass through /home/example/www/example.com/index.php
[example.com/sid#8475130][rid#b6cd7058/initial] (3) [perdir /home/example/www/example.com/] strip per-dir prefix: /home/example/www/example.com/404 -> 404
[example.com/sid#8475130][rid#b6cd7058/initial] (3) [perdir /home/example/www/example.com/] applying pattern '^(.*)$' to uri '404'
[example.com/sid#8475130][rid#b6cd7058/initial] (2) [perdir /home/example/www/example.com/] rewrite '404' -> '/index.php?404'
[example.com/sid#8475130][rid#b6cd7058/initial] (3) split uri=/index.php?404 -> uri=/index.php, args=404
[example.com/sid#8475130][rid#b6cd7058/initial] (2) [perdir /home/example/www/example.com/] trying to replace prefix /home/example/www/example.com/ with /
[example.com/sid#8475130][rid#b6cd7058/initial] (1) [perdir /home/example/www/example.com/] internal redirect with /index.php [INTERNAL REDIRECT]
[example.com/sid#8475130][rid#b6ce5440/initial/redir#1] (3) [perdir /home/example/www/example.com/] strip per-dir prefix: /home/example/www/example.com/index.php -> index.php
[example.com/sid#8475130][rid#b6ce5440/initial/redir#1] (3) [perdir /home/example/www/example.com/] applying pattern '^(.*)$' to uri 'index.php'
[example.com/sid#8475130][rid#b6ce5440/initial/redir#1] (1) [perdir /home/example/www/example.com/] pass through /home/example/www/example.com/index.php

访问日志摘要

"GET /article/4 HTTP/1.1" 302 4095 "-"
"GET /404 HTTP/1.1" 200 2405 "-"

答案1

您原来的重写规则看起来很简单:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteOptions inherit

    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-s
    RewriteCond %{REQUEST_FILENAME} !-l
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_URI} !^/index\.php
    RewriteRule ^(.*)$ /index.php?$1 [L]
</IfModule>

您是否尝试过使用简单的 SEO/SEF,.htaccess例如与 WordPress 捆绑在一起的 SEO/SEF?这里是,但我添加了RewriteOptions inherit您原始设置中的规则:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteOptions inherit

    RewriteBase /
    RewriteRule ^index\.php$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]
</IfModule>

答案2

日志表明您的规则运行正常。

脚本index.php使用参数执行?article/4,并且脚本以 302 重定向响应到/404。这些重写规则中没有[R]任何选项,因此一定是脚本发出了重定向。

浏览器发出了后续请求/404并生成了 200 响应。


/404我怀疑你有三个问题。第一个是你的脚本在找不到内容时向 URL 发出 302 响应。它应该发出 404 响应。

第二个是你的/404脚本发出 200 响应。它应该发出 404 响应。

第三,您的 index.php 脚本不知道如何处理参数?article/4。我不知道您的脚本如何工作,但我建议对脚本本身进行一些调试可能会解决您的问题。echo()在脚本的各个阶段使用一些变量或类似的东西file_put_contents("/var/log/apache2/example.com.debug.log", time()." ".$variable."\n", FILE_APPEND)

相关内容