Apache RewriteRule 和跳过逻辑

发布于 2024-09-15 18:49:54 字数 698 浏览 1 评论 0原文

我在这里几乎碰壁了。据我所知,这应该有效,但事实并非如此。

我有一个本地开发地址,其通配符子域为 *.localhost,友好 URL 为 /[0-9]/somestring。我想做的是将 username.localhost/1/page 设为 localhost?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/page 页,第一条规则意味着跳过匹配并跳过,但无法正确重写。但是,如果我删除前 2 条规则,它将很好地重写 /1/page 页面。

就好像它没有跳过,但如果我将其更改为 S=2,它就会跳过这两个规则。啊。有什么想法吗?

I've pretty much hit a wall here. As far as I can tell, this should work, but it doesn't.

I have a local development address with a wildcard subdomain of *.localhost, and friendly URLs of /[0-9]/somestring. What I am trying to do is have username.localhost/1/page to localhost?pageId=1&username=username. The complication comes in trying to get both the home page at username.localhost as well as the individual pages i.e. username.localhost/1/page to both work.

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

With /1/page pages, the first rule meant to skip matches and skips, but fails to rewrite correctly. However, if I remove the first 2 rules, it'll rewrite /1/page pages just fine.

It's as if it's not skipping, yet if i change it to S=2, it skips both rules. Argh. Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

凡尘雨 2024-09-22 18:49:54

据我所知,它实际上正在做您期望它做的事情。只是,在这样做之后,它会再次尝试你的规则集,这会把事情搞砸。发生的事情看起来更具体如下:

  • 发出对 http://username.localhost/1/page 的请求
  • 输入 1/page 与第一条规则 匹配S=1 被应用
  • 输入 1/page 匹配第三条规则,URL 被重写为 index.php?pageId=1&username=username
  • 内部重定向由 mod_rewrite 执行(到目前为止一切都很好,但是...)
  • mod_rewrite 处理内部重定向,并再次开始处理规则
  • 输入 index.php 与第一条规则不匹配,S=1 未应用
  • 输入 index.php 与第二条规则匹配,URL 重写为 index.php php?username=username
  • (内部重定向再次发生,执行相同的重写,但 mod_rewrite 检测到重定向循环并立即停止处理)

有几种不同的方法可以解决此问题,但我认为这里最简单的方法是确保文件不存在,然后将最后一个规则中的模式滚动到前一个规则的条件中:

# 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

From what I can tell, it actually is doing what you expect it to do. Only, after it does that, it has a second go at your rule set, which messes things up. What's happening looks more specifically like this:

  • Request to http://username.localhost/1/page is made
  • The input 1/page matches the first rule, S=1 is applied
  • The input 1/page matches the third rule, URL is rewritten to index.php?pageId=1&username=username
  • An internal redirection is performed by mod_rewrite (all good so far, but...)
  • mod_rewrite handles the internal redirection, and starts processing the rules again
  • The input index.php does not match the first rule, S=1 is not applied
  • The input index.php matches the second rule, URL is rewritten to index.php?username=username
  • (the internal redirection occurs again, the same rewrite is performed, but mod_rewrite detects the redirection loop and stops processing now)

There are a few different ways to fix this, but I think the easiest one here is to just make sure the file doesn't exist, and then roll the pattern from the last rule into a condition for the previous one:

# 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

Edit: The above version also catches things that don't match your page pattern and acts like they were index.php?username=username, which might not be desired. The following would avoid that, and is a bit more concise anyway:

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文