我刚刚接手了一个老旧的网站,该网站已从 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'];
这样你甚至不需要重写模块。显然它的性能会稍差一些,也许不太优雅,但至少你不必转换链接/文件名。