【问题标题】:Lighttpd's mod_rewrite moduleLighttpd 的 mod_rewrite 模块
【发布时间】:2013-04-20 18:31:38
【问题描述】:

我对 Lighty 的 mod_rewrite 模块有疑问。

我正在尝试这样做:example.com/index.php?search=whatever,显示为 example.com/whatever 或 example.com/search/whatever(尚未决定 - 不太了解搜索引擎优化)

虽然我希望它像上面那样运行,但我还想从重写中排除所有物理目录和所有文件,例如目录 /images/ 和文件 index.php、favicon.ico、style.css 等,因为它的行为很奇怪。

我将如何实现这一目标?我尝试了以下方法,这对我想要的效果很好,但在排除目录和文件时并没有真正起作用:

url.rewrite-once = (
"^/([a-zA-Z0-9_-]+)" => "/index.php?search=$1",
"^/(images|js|wp-content)/(.*)" => "$0",
"(.*\.php|.*\.css|favicon.ico)" => "$0" )

顺便问一下,这有什么区别:

"^/([a-zA-Z0-9_-]+)" => "/index.php?search=$1",

还有这个:

"^/(.*)$" => "/index.php?search=$1"

【问题讨论】:

    标签: mod-rewrite url-rewriting lighttpd subdirectory lighty


    【解决方案1】:

    为了避免添加大量 RewriteCond 指令来检查访问者的请求不是实际文件而不是人工路径,我建议使用/search/whatever 模式而不是/whatever 模式。然后,只要您从不创建名为“search”的实际目录,您就永远不需要检查以/search 开头的路径是否是实际文件路径。所以你的 RewriteRule 变得这么简单:

    RewriteRule ^/search/([a-zA-Z0-9_-]+)$ /index.php?search=$1
    

    (我对Lighty不熟悉,所以我不确定如何将其转换为url.rewrite-once指令,但这是一个如此简单的重写,应该很简单。)

    但是,访问者的浏览器现在会认为他们正在查看的页面位于名为“搜索”的子目录中,因此,如果您有任何使用相对路径(未锚定到根的路径)指定的图像元素或 CSS 文件目录),例如src="images/photo.jpg" 或href="stylesheets/clean.css",那么浏览器会认为这些路径是相对于“搜索”目录的,并会分别向您的网络服务器询问/search/images/photo.jpg 和/search/stylesheets/clean.css。

    有两种方法可以做到这一点。第一个是将所有页面装饰(图像、样式表、JavaScript)路径更改为绝对路径。也就是说,更改路径,使其以代表网站根目录的正斜杠开头。因此,您的图像路径需要更改为src="/images/photo.jpg",您的样式表路径需要更改为href="/stylesheets/clean.css"。开头的正斜杠告诉网络浏览器该路径从站点的根目录开始,因此没有歧义。

    第二个选项是创建复杂的 RewriteRules 以将图像、样式表、脚本文件等的请求重定向到正确的目录。如果您在很多不同的目录中有很多媒体类型,并且您需要它们从很多不同的子目录(虚拟和/或其他)中工作,这往往会变得丑陋和脆弱。

    您选择哪个选项取决于您的要求和偏好。

    关于您关于[a-zA-Z0-9_-]+ 和.* 之间区别的问题,第一个模式只允许字母a 到z(小写或大写)、数字、下划线和连字符。第二种模式允许任何字符。出于安全和调试原因,通常最好使用将字符限制为仅应允许的字符的模式。所以我会使用第一个模式,如果需要,添加额外的允许字符,而不是允许所有字符。

    【讨论】:

    • 好的,帮助很大!但现在我发现了另一个问题。每当我使用特殊字母搜索时,例如 ö、ü、ï 等,它都不起作用。我尝试为所有这样的字母添加 \p{L}: "^/search/([0-9\p{L}_-]+)" => "/index.php?search=$1"但这根本没有帮助。顺便说一句,每当我搜索诸如“john example”之类的名称时,它只会搜索空格之前的任何内容。我试图用“john+example”、“john_example”和“john-example”来解决这个问题,但这些都不起作用。我的 RewriteRule 是否遗漏了什么?
    • 当我允许所有字符通过.* 模式时,一切似乎都正常。
    • 我不熟悉\p{L} 语法,但正则表达式确实提供了\w 字字符类(匹配字母、数字和取消划线)。所以你可以尝试([\w+-]+) 来允许单词字符、加号和连字符。您也可以在字符类中输入一个空格(但要确保文字连字符是方括号中的最后一个字符),但在原始 URL 中往往不允许使用空格,所以我不知道空格是否会永远存在匹配。
    • 好吧,我不知道我做错了什么,但使用\w 和你提供的加号和连字符解决了“john+example”的问题。但是,当使用 %F6(相当于我的 Chrome 浏览器地址栏中的 ö)搜索内容时,它不起作用,而使用 .* 语法/模式。
    • 可能\w 只匹配基本的 a 到 z 字母。或者您可能需要在方括号中的最后一个连字符之前添加一个% 符号。无论哪种方式,如果.* 适合您,那么在这种情况下使用它可能不会有什么坏处。只需确保您的 PHP 脚本在对值执行任何敏感操作(例如将其添加到数据库查询)之前检查提供的值是否包含代码注入。
    猜你喜欢
    • 1970-01-01
    • 2010-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-09
    • 1970-01-01
    • 1970-01-01
    • 2011-05-30
    相关资源
    最近更新 更多