Apache Mod Rewrite for Pretty URL无效

时间:2013-03-23 19:01:03

标签: apache .htaccess mod-rewrite

我正在尝试弄清楚如何执行apache mod_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,保持网址简洁。

最近尝试过的代码

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 &lt; - 这个似乎导致了问题

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]

谢谢大家的帮助。我花了两天的时间试图让它工作!!!

4 个答案:

答案 0 :(得分:2)

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

假设index.php.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]

匹配所有^并且不会substitution,但会以标记[L]结束重写周期

您可以使用标志E=SEO:1自行设置变量,而不是使用系统提供的环境STATUS / REDIRECT_STATUS,然后使用

RewriteCond %{ENV:REDIRECT_SEO} 1

对于REDIRECT_前缀,请参阅Available Variables

答案 1 :(得分:0)

你可以试试这个:

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

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

答案 2 :(得分:0)

如果您希望论坛([0-9]+)为字母,则只需将其更改为([a-z]+),如果您希望将其更改为字母数字,则将其更改为([a-z0-9]+)和{{ 1}}如果用连字符和下划线。如果您希望手动设置限制,则可以使用此格式([a-z0-9-_]+)执行此操作。你知道吗,加号已经消失,因为它限制了([a-z0-9-_]{1,40}) 1对任何东西,而[chars]{1,40}限制为1到40,你可以改变它。 / p>


你知道真正的问题是什么吗?是我的压力..想象一下,即使我知道你想将 / $ var 重新映射到 /index.php?URL=pages/$var.php 我还在尝试给你一个错误的信息,将 /index.php?URL=pages/$var.php 重写为 / $ var 。我刚刚意识到睡了4个小时之后。当你睡觉的时间不对时,你有没有看到发生了什么?当我的大脑运作良好时,也许我会给你的规则是:

[chars]

为什么观众会发生这种情况..我以前的代码需要被删除。

答案 3 :(得分:0)

您的方法似乎很好,但您的RewriteCond与您的要求不匹配

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

表示“如果某人请求以'index.php开头'的内容,则重写URL” - 但这不是任何人要求的内容。您希望访问者请求漂亮的网址。

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

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

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

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

RewriteCond %{REQUEST_FILENAME} !-f  

表示“如果用户请求找不到文件的网址,请根据即将发布的RewriteRule重写网址。”