2010-08-23 76 views
0

我已经在这里打了一堵墙。据我所知,这应该起作用,但事实并非如此。Apache重写规则和跳过逻辑

我有一个本地开发地址,包含* .localhost的通配符子域,以及/ [0-9]/somestring的友好URL。我想要做的是有username.localhost/1/pagelocalhost?pageId=1&username=username。复杂性在于试图将username.localhost的主页以及各个页面(即username.localhost/1/page)都起作用。

RewriteRule ^([0-9]+)/[a-zA-Z0-9\-\_\,\.]+$ - [S=1] 
RewriteCond %{HTTP_HOST} !^www.* [NC] 
RewriteCond %{HTTP_HOST} ^([^\.]+)\.localhost 
RewriteRule ^index.php$ index.php?username=%1 
RewriteRule ^([0-9]+)/[a-zA-Z0-9\-\_\,\.]+$ index.php?pageId=$1&username=%1 

使用/ 1 /页面页面,第一条规则用于跳过匹配和跳过,但无法正确重写。但是,如果我删除前两条规则,它会重写/ 1 /页面就好了。

就好像它没有跳过,但如果我将它更改为S = 2,它将跳过这两个规则。哎呀。有任何想法吗?

回答

1

从我所知道的,它实际上做你期望它做。只有在这样做之后,它会在你的规则集中进行第二次尝试,这会弄乱一切。发生了什么事更具体是这样的:

  • 请求http://username.localhost/1/page
  • 输入1/page匹配的规则,S=1应用
  • 输入1/page符合第三条规则,URL改写为index.php?pageId=1&username=username
  • 通过mod_rewrite执行内部重定向(目前为止都很好,但是...)
  • mod_rewrite处理内部重定向,并且sta RTS处理规则再次
  • 输入index.php不匹配的第一个规则,S=1不施加
  • 输入index.php匹配第二规则,URL被改写为index.php?username=username
  • (内部重定向再次发生时,相同的重写被执行,但mod_rewrite检测重定向循环,现在停止处理)

有几种不同的方式来解决这个问题,但我认为最简单的一个在这里只是确保文件不存在,然后从最后一个RU滚动模式乐成前一个条件:

# Make sure we haven't rewritten to a file yet (the "directory" gets processed 
# before DirectoryIndex index.php is applied) 
RewriteCond %{REQUEST_FILENAME} !-f 
# Check that the input doesn't match the pattern we want handled later 
RewriteCond $0   !^([0-9]+)/[a-zA-Z0-9_,.-]+$ 
RewriteCond %{HTTP_HOST} !^www.* [NC] 
RewriteCond %{HTTP_HOST} ^([^\.]+)\.localhost 
RewriteRule ^.*$ index.php?username=%1 

RewriteRule ^([0-9]+)/[a-zA-Z0-9_,.-]+$ index.php?pageId=$1&username=%1 

编辑:以上版本还捕捉的东西不符合你的页面模式,就像他们index.php?username=username,这可能是不希望的。以下将避免这一点,并且无论如何更简洁一些:

RewriteCond %{HTTP_HOST} !^www.* [NC] 
RewriteCond %{HTTP_HOST} ^([^\.]+)\.localhost 
RewriteRule ^$ index.php?username=%1 

RewriteRule ^([0-9]+)/[a-zA-Z0-9_,.-]+$ index.php?pageId=$1&username=%1 
+0

感谢您的回答。我可以看到一秒钟如何贯穿整个规则的逻辑可能会在整个事情中引发一场大问题。对不起,如果我有点密集,但我无法跟随你的解决方案如何解决它。 REQUEST_FILENAME出来是index.php,它总是会存在的,因此尝试这似乎并没有泛滥。 – 2010-08-24 13:18:57

+0

@Zurahn - 对于'http:// username.localhost /'的请求将有'/ website/root/dir /'的初始'%{REQUEST_FILENAME}',因为域后没有请求路径。这不是一个文件,所以在第一遍中''-f'的条件是真的。在随后的传递过程中(在这种情况下,因为有'RewriteRule',但是如果应用了DirectoryIndex,情况也是如此),'%{REQUEST_FILENAME}'变成'/ website/root/dir/index.php',是一个文件,导致条件失败,并且不允许意外再次执行第一次重写。 – 2010-08-24 14:32:27

+0

感谢您的帮助。我会与你提供的东西一起工作,并认为我应该能够管理它。 – 2010-08-24 14:49:29