2

我试图弄清楚如何做一个 apachemod_rewrite来重新映射$_GET

我要完成的工作:

目前,要进入页面,必须去

http://www.domain.com/index.php?URL=pages/the-page.php

我希望它以两种方式工作:

如果有人去domain.com/the-page,它会将他们带到上面,但保持它看起来像这样。其次,如果有人访问http://www.domain.com/index.php?URL=pages/the-page.php,它仍然会显示为domain.com/the-page,从而保持 URL 简洁明了。

最近尝试的代码

Options +FollowSymlinks
RewriteEngine on
RewriteCond %{REQUEST_URI} ^/index\.php$
RewriteCond %{QUERY_STRING} URL=pages/([a-z0-9-_]+)\.php$
RewriteRule ^(.*) /%1

我很确定我在 apache 中正确设置了所有内容httpd.conf。我正在使用 XAMPP 在本地进行测试,在更改时重新启动 apache,仍然没有。我哪里错了?

我宁愿在 .htaccess 中处理这个

我正在使用 XAMPP localhost 并尝试在实时服务器上。

日志文件:

127.0.0.1 - - [05/Apr/2013:16:50:43 --0400] [localhost/sid#2f3140][rid#3b14068/initial] (3) [perdir C:/xampp/htdocs/cdi/] strip per-dir prefix: C:/xampp/htdocs/cdi/index.php -> index.php

127.0.0.1 - - [05/Apr/2013:16:50:43 --0400] [localhost/sid#2f3140][rid#3b14068/initial] (3) [perdir C:/xampp/htdocs/cdi/] applying pattern '^(.*)' to uri 'index.php'

127.0.0.1 - - [05/Apr/2013:16:50:43 --0400] [localhost/sid#2f3140][rid#3b14068/initial] (1) [perdir C:/xampp/htdocs/cdi/] pass through C:/xampp/htdocs/cdi/index.php

使用 Olaf 的脚本更新日志(最后一条规则被注释掉)

127.0.0.1 - - [05/Apr/2013:20:02:24 --0400] [localhost/sid#2e3140][rid#3b14090/initial] (3) [perdir C:/xampp/htdocs/cdi/] strip per-dir prefix: C:/xampp/htdocs/cdi/index.php -> index.php

127.0.0.1 - - [05/Apr/2013:20:02:24 --0400] [localhost/sid#2e3140][rid#3b14090/initial] (3) [perdir C:/xampp/htdocs/cdi/] applying pattern '^' to uri 'index.php'

127.0.0.1 - - [05/Apr/2013:20:02:24 --0400] [localhost/sid#2e3140][rid#3b14090/initial] (3) [perdir C:/xampp/htdocs/cdi/] strip per-dir prefix: C:/xampp/htdocs/cdi/index.php -> index.php

127.0.0.1 - - [05/Apr/2013:20:02:24 --0400] [localhost/sid#2e3140][rid#3b14090/initial] (3) [perdir C:/xampp/htdocs/cdi/] applying pattern '^index\.php$' to uri 'index.php'

127.0.0.1 - - [05/Apr/2013:20:02:24 --0400] [localhost/sid#2e3140][rid#3b14090/initial] (2) [perdir C:/xampp/htdocs/cdi/] rewrite 'index.php' -> '/newhome?'

127.0.0.1 - - [05/Apr/2013:20:02:24 --0400] [localhost/sid#2e3140][rid#3b14090/initial] (3) split uri=/newhome? -> uri=/newhome, args=<none>

127.0.0.1 - - [05/Apr/2013:20:02:24 --0400] [localhost/sid#2e3140][rid#3b14090/initial] (2) [perdir C:/xampp/htdocs/cdi/] explicitly forcing redirect with http://localhost/newhome <--这似乎是导致问题的原因

127.0.0.1 - - [05/Apr/2013:20:02:24 --0400] [localhost/sid#2e3140][rid#3b14090/initial] (1) [perdir C:/xampp/htdocs/cdi/] escaping http://localhost/newhome for redirect

127.0.0.1 - - [05/Apr/2013:20:02:24 --0400] [localhost/sid#2e3140][rid#3b14090/initial] (1) [perdir C:/xampp/htdocs/cdi/] redirect to http://localhost/newhome [REDIRECT/302]

感谢所有帮助的人。我花了 2 天的时间试图让它工作!!!

4

4 回答 4

2

基本上,你需要两条规则。一条规则将客户端重定向到干净的 URL,另一条规则将漂亮的 URL 内部重写为真实内容index.php

假设index.phpand.htaccess在目录中cdi

RewriteEngine on

# prevent endless loop
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]

# redirect the client
RewriteCond %{QUERY_STRING} URL=pages/(.+?)\.php
RewriteRule ^index\.php$ /cdi/%1? [R,L]

# exclude rewriting all files located in /cdi/files
RewriteCond %{REQUEST_URI} !^/cdi/files/
# rewrite to real content
RewriteRule ^.*$ /cdi/index.php?URL=pages/$0.php [L]

更新

当请求为/cdi/index.php?URL=pages/abc.php时,第二条规则提取需要的URL部分并将客户端重定向到新的 URL 路径。然后客户端请求新的 URL /cdi/abc,第三条规则接受这个并对真实内容进行内部重写。

这一切都可以正常工作,但会无限期地重写和重定向。为了打破这个无休止的规则,第一条规则检查环境%{ENV:...},如果请求已经被重定向REDIRECT_STATUS,然后停止循环RewriteRule

RewriteRule ^ - [L]

它匹配所有内容^并且不进行替换,但以标志结束重写周期[L]

除了使用系统提供的环境STATUS/ REDIRECT_STATUS,您还可以自己使用标志设置一个变量E=SEO:1,然后使用

RewriteCond %{ENV:REDIRECT_SEO} 1

有关REDIRECT_前缀,请参阅可用变量

于 2013-04-05T21:22:01.640 回答
0

您的方法似乎很好,但您的要求RewriteCond不符合您的要求:

RewriteCond %{REQUEST_URI} ^index.php?URL=pages

意思是“如果有人请求以'index.php”开头的东西,则重写URL——但这不是任何人都会请求的。您希望您的访问者请求漂亮的 URL。

如果您的服务器只需要为 /the-page 提供这些请求,则可以完全放弃该条件。然后将重写任何 URL。(注意:这可能不是你想要的!)

否则,条件应该是这样的:

RewriteCond %{REQUEST_URI} ^[a-z0-9-_]{1,40}

如果你不想弄乱正则表达式,你也可以试试这个:

RewriteCond %{REQUEST_FILENAME} !-f  

这意味着“如果用户请求一个找不到文件的 URL,则根据即将到来的RewriteRule.

于 2013-04-05T20:55:24.247 回答
0

如果您希望该组([0-9]+)按字母顺序排列,那么只需将其更改为([a-z]+)and 如果您希望它是字母数字组,则将其更改为([a-z0-9]+),([a-z0-9-_]+)如果带有连字符和下划线。如果您希望它手动设置它们的限制,您可以使用这种格式来做到这一点([a-z0-9-_]{1,40})。你看到了吗,加号消失了,因为它限制了[chars]with 1 到任何东西,并且{1,40}限制了[chars]with 1 到 40,你可以改变它。


你知道真正的问题是什么吗?是我的压力吗.. 想象一下,即使我知道你想将/$var重新映射到/index.php?URL=pages/$var.php我仍然试图给你一个错误的信息,它将重写/index.php?URL =pages/$var.php进入/$var。在我睡了 4 个小时之后,我才意识到这一点。当你的睡眠时间不对时,你看到发生了什么吗?当我的大脑运转良好时,也许我会给你的一条规则是:

RewriteRule ^([a-z0-9-_]+)/?$ /index.php?URL=pages/$1.php

为什么观众让这件事发生……我以前的代码需要被否决。

于 2013-04-05T16:45:00.877 回答
0

你可以试试这个:

RewriteRule ^/([a-z0-9_-]{1,40})/?$ index.php?URL=pages/$1.php

虽然理想情况下您可能希望摆脱查询字符串变量的“pages/”部分,因为这个固定常量可以由 index.php 脚本处理。

于 2013-03-24T19:11:53.420 回答