我刚刚承担了一个从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你不必转换链接/文件名。