configurationhtaccess / mod_rewrite在URL中提供带有问号的静态文件

我刚刚承担了一个从asp转换为静态html的古代网站,由约6000个文件组成。 但是,我的服务器不喜欢文件名,给出了一个404错误。 这些url都是以下格式:

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

其中id始终是一个整数,而a总是一串字符和数字。

有什么办法可以使用htaccess和mod_rewrite来告诉它,问号是URL的一部分,而不是表示一个查询string?

你可能已经知道你不是第一个 有这个需要的人 🙂

 # 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] 

关键是添加一个redirect和NE / noescape的组合,以确保Apache不逃避我们不想逃脱。

上面的规则意味着整个网站在这个重写将会对待? 作为文件名的一部分。 如果你需要它匹配你的filename.asp – 只需将其添加到RewriteRule

我会build议重写直接提供文件,通过转义“?” 到“\%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] 

首先,我们testing文件是否存在(请参阅下一段),然后检查是否有查询string(否则像往常一样提供文件),然后添加“?” 和原始查询string并提供。

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

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

警告:我没有彻底testing这个解决scheme,所以错误可能会持续下去。

我用wget --mirror转换了一个古老的Joomla网站。 在我的情况下,所有的链接都通过index.php文件,所以他们都是像site.com/index.php?blabla=haha

我已经解决了这个问题,通过添加一个index.php文件与以下内容:

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

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