我的 .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)
。