【问题标题】:Apache Mod Rewrite for Pretty URLs isn't workingApache Mod Rewrite for Pretty URLs 不起作用
【发布时间】:2013-03-23 19:01:02
【问题描述】:

我正在尝试弄清楚如何使用 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,从而保持 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 天的时间试图让它工作!!!

【问题讨论】:

  • 这仍然是您当前完整的 .htaccess 吗?
  • 没有,但是我已经注释掉了我添加的 httpd.conf 代码,并按照说明删除了除了下面的代码之外的所有 .htaccess。
  • 您到底想达到什么目标?如果只是将来自/abc 的传入请求重写为/index.php?URL=pages/abc.php,则删除RewriteCond。单独的 RewriteRule 应该可以正常工作。
  • 更新了原始问题。
  • 我刚刚回答了一个类似的问题,见stackoverflow.com/a/15839460/1741542

标签: apache .htaccess mod-rewrite


【解决方案1】:

基本上,您需要两条规则。一条规则将客户端重定向到干净的 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]标志结束重写周期

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

测试这个变量
RewriteCond %{ENV:REDIRECT_SEO} 1

有关REDIRECT_ 前缀,请参阅Available Variables

【讨论】:

  • 天哪,它真的做了什么!!!拳头甚至可以远程更改 URL。不幸的是,它的打印是这样的http://localhost/subfolder/the-page?URL=pages/subfolder/the-page.php
  • 顺便问一下,$0 是怎么回事?我以为后路从$1开始。
  • @yUnoDOWNVOTE 我忘了在规则末尾添加问号?。请参阅更新的答案。 $0是整个模式,$1是第一组(...)$2第二组(...)等等。
  • @Servant 正确。 .* 没有 /cdi。因此,/$0 会尝试在根文件夹中而不是在 cdi 中请求它。
  • @Servant 我试图更彻底地解释一下规则在做什么。请查看更新的答案。
【解决方案2】:

你可以试试这个:

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

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

【讨论】:

  • 注意:[a-z0-9_]等于[\w],所以[a-z0-9_-]可以压缩成[\w-]
  • 我已经编辑了代码,因为我刚刚意识到您使用的是 httpd.conf 而不是本地 .htaccess 文件,因此在正则表达式模式的开头需要一个正斜杠^ 符号。
  • 我仍然无法让它工作。我尝试了几种组合。另外,我在 .htaccess 中这样做(尝试了两种代码)
【解决方案3】:

您的方法看起来不错,但您的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重写该URL。”

【讨论】:

  • 很高兴看到RewriteRule。我开始理解正则表达式。我已经多次阅读文档。
【解决方案4】:

如果您希望组 ([0-9]+) 是字母组,只需将其更改为 ([a-z]+),如果您希望它是字母数字组,则将其更改为 ([a-z0-9]+),如果使用连字符和 ([a-z0-9-_]+),则一个下划线。如果您希望它手动设置限制,您可以使用这种格式([a-z0-9-_]{1,40}) 来实现。看到了吗,加号不见了,因为它将 [chars] 的 1 限制为任何值,{1,40}[chars] 的 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

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

【讨论】:

  • 从我一直在阅读的内容来看,这两个都更有意义,但由于某种原因它仍然无法正常工作。我一直在 .htaccess 中进行 302 重定向,但我没有一次重写工作。引擎已加载并打开,即使遵循符号链接。也许我应该尝试在 Apache 的 httpd.conf 中的目录中执行此操作?
  • 这些代码用于 .htaccess 文件。但是,您仍然可以在其他文件中尝试。您是否曾经尝试过仅使用 Options +FollowSymlinksRewriteEngine on 的代码本身?
  • 是的,我已经尝试将上述内容放在/pages 的.htaccess 中,仍然没有运气。也在本地和实时服务器上尝试过。我宁愿使用 .htaccess,因为我的一个客户有一个非常严格的共享主机。
  • 你的意思是将domain.com/$var重新映射到domain.com/index.php?URL=pages/$var.php
  • 我正在尝试删除除pages/ 之后的所有内容。我也想摆脱 .php 扩展名。使用日志信息更新了原始代码。
猜你喜欢
  • 1970-01-01
  • 2016-04-01
  • 2017-07-10
  • 1970-01-01
  • 2012-07-21
  • 2011-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多