配置 htaccess/mod_rewrite 以在 URL 中使用问号来提供静态文件

配置 htaccess/mod_rewrite 以在 URL 中使用问号来提供静态文件

我刚刚接手了一个老旧的网站,该网站已从 asp 转换为静态 html,包含约 6,000 个文件。但是,我的服务器不喜欢这些文件名,并给出 404 错误。所有 URL 的格式如下:

filename.asp?id=123&a=something.html

其中id始终是一个整数,并且a始终是一个由字符和数字组成的字符串。

有什么方法可以使用 htaccess 和 mod_rewrite 来告诉它问号是 URL 的一部分而不是表示查询字符串?

答案1

你可能已经知道你不是第一人称有这个需要:)

# Allow filenames containing '?' to be served by escaping the '?' in the HTTP
# request so it's not interpreted as a query string.
#
# Apache 2.2: set query string to empty by ending rewritten path with '?'.
# Apache 2.4: use the qsdiscard flag instead
#
RewriteCond %{QUERY_STRING} !=""
RewriteRule ^/(.*) /$1\%3F%{QUERY_STRING}? [noescape,last,redirect]

关键是添加重定向和NE/无逃逸以确保 apache 不会逃脱我们不想逃脱的东西。

上述规则意味着此重写下的整个网站将被视为?文件名的一部分。如果您需要使其与您的匹配filename.asp- 只需将其添加到 RewriteRule

答案2

我建议重写以直接提供文件,通过将“?”转义为“\%F3”。

要提供文件:

RewriteCond %{QUERY_STRING} !=""
RewriteRule ^(.*)$ $1\%3F%{QUERY_STRING}? [L]

对文件夹执行相同操作(即提供 index.html - 调整 index.html 以满足您的需要)

RewriteCond %{REQUEST_FILENAME} ^.*/$
RewriteCond %{QUERY_STRING} !=""
RewriteRule ^(.*)/$ $1/index.html\%3F%{QUERY_STRING}? [L]

首先,我们测试文件是否存在(请参阅下一段相关内容),其次我们检查是否有查询字符串(否则,照常提供文件),然后添加“?”和原始查询字符串并提供它。

我在末尾添加了“?”,以删除 QueryString(因为它已被处理),并避免第二次应用规则(例如:如果在子目录中提供文件)。其他解决方案是使用“END”标志(请参阅http://httpd.apache.org/docs/current/en/mod/mod_rewrite.html#rewriterule)。根据同一页面,并且正如@csharkey 和@Gavin C 所提到的,可以在 apache 2.4 中添加 [qsdiscard]:

RewriteRule ^(.*)/$ $1/index.html\%3F%{QUERY_STRING}? [L,qsdiscard]

警告:我没有彻底测试这个解决方案,所以可能仍然存在错误。

答案3

我已经用 转换了一个古老的 Joomla 网站wget --mirror。在我的例子中,所有链接都经过 index.php 文件,因此所有链接都类似于site.com/index.php?blabla=haha

我通过添加包含以下内容的 index.php 文件解决了该问题:

<?php

include 'index.php?' . $_SERVER['QUERY_STRING'];

这样你甚至不需要重写模块。显然它的性能会稍差一些,也许不太优雅,但至少你不必转换链接/文件名。

相关内容