我有一个博客。 博客存储在我网站的/blog/前缀下。 它具有通常的博客URL,因此文章的URL格式为/blog/:year/:month/:day/:title/ 。
首先,我想自动将访问者redirect到www子域(以防他们离开),并在内部将根URL重写为/blog/ ,以便博客的首页出现在站点的首页。 我用.htaccess文件中的下列一组重写规则完成了这个工作:
RewriteEngine On # Rewrite monkey-robot.com to www.monkey-robot.com RewriteCond %{HTTP_HOST} ^monkey-robot\.com$ RewriteRule ^(.*)$ http://www.monkey-robot.com/$1 [R=301,L] RewriteRule ^$ /blog/ [L] RewriteRule ^feeds/blog/?$ /feeds/blog/atom.xml [L]
这工作正常。 问题是,博客的首页现在出现在两个不同的URL: /和/blog/ 。 所以我想将 /blog/ URL redirect到根URL。 最初我试图用以下一组重写规则来实现这一点:
RewriteEngine On # Rewrite monkey-robot.com to www.monkey-robot.com RewriteCond %{HTTP_HOST} ^monkey-robot\.com$ RewriteRule ^(.*)$ http://www.monkey-robot.com/$1 [R=301,L] RewriteRule ^$ /blog/ [L] RewriteRule ^blog/?$ / [R,L] RewriteRule ^feeds/blog/?$ /feeds/blog/atom.xml [L]
但是,这给了我一个无限的redirect(也许是因为前面的规则?)。 所以然后我尝试了这一套:
RewriteEngine On # Rewrite monkey-robot.com to www.monkey-robot.com RewriteCond %{HTTP_HOST} ^monkey-robot\.com$ RewriteRule ^(.*)$ http://www.monkey-robot.com/$1 [R=301,L] RewriteRule ^$ /blog/ [L] RewriteRule ^blog/?$ http://www.monkey-robot.com/ [R,L] RewriteRule ^feeds/blog/?$ /feeds/blog/atom.xml [L]
但是,我收到了500内部服务器错误与以下日志消息:
无效的命令'[R,L]',可能是拼写错误或由未包含在服务器configuration中的模块定义的
是什么赋予了? 我不认为[R,L]是一个语法错误。
我怀疑你可以通过把重写指令放在主虚拟主机configuration中而不是在.htaccess文件中来避免第二个规则集中的无限循环。 无论如何,这通常是一个很好的做法,因为重写的速度比虚拟主机快得多,如果你能告诉Apache忽略.htaccess文件,你可以获得更多的速度优势。
这个背后的逻辑在mod_rewrite技术文档中有解释。 这就是要点:如你所知,重写规则可以改变给定请求对应的文件名,甚至可以改变生成的文件所在的目录。事实上,你的
RewriteRule ^$ /blog/
是一个完美的例子,它将文档根目录更改为blog目录。 但是Apache需要知道目录,以便找出哪个.htaccess文件来检查请求。 也许你可以在这里看到问题:当Apache到达你的.htaccess文件时,它已经确定了它应该访问的文件的名称,这意味着你的重写规则适用的时间已经太晚了。
Apache在内部通过创build一个新的子请求来解决这个问题,这个子请求从一开始就开始处理,并且将你的.htaccess文件中的规则注入到处理stream中,以便将它们应用到请求中。 作为这个的一个副作用, 所有适用的重写规则再次被应用,这意味着当你在一个.htaccess文件中使用它时, [L]标志是一种谎言。 所以,尽pipe你把[L]放在你的规则上,试图强迫它成为最后的规则,但它确实不是。 当Apache处理其内部的子请求时,所有的规则都会被重新应用。
如果您无法访问主服务器configuration,则可以这样做:
RewriteRule ^/blog/?$ / [R,L,NS]
NS标志防止该规则应用于子请求。
读完评论后,我认为最简单的解决scheme是将根页面重写为实际的文件 ( index.html ,我想呢?)。
RewriteRule ^blog/$ / [R,L] RewriteRule ^$ /blog/index.html [L]
这种方式循环可以避免。 一个问题仍然存在 – / /blog/index.html仍然可以从外部访问 。 如果这不是一种select,我认为你最好的select就是遵循David的build议,并把configuration提升一级。
我想到的一些select :
/blog/index.html访问和使用链接规范 (不是最好的,但容易) /blog/index.phpredirect到/脚本级别