用两个重写规则改变请求

时间:2013-08-21 18:15:25

标签: apache .htaccess mod-rewrite

所以我的网络服务器正在提供像file_name.php这样的文件。我想这样做,因此对file-name.php的请求被透明地重定向到file_name.php,并且对file_name.php的请求通过301重定向显式重定向到file-name.php。

即。您请求file_name.php并将301重定向到file-name.php,它会透明地加载file_name.php。

不幸的是,我为完成此操作而编写的.htaccess文件无效。这是:

# make it so files with slashes that don't exist transparently redirect to files with underscores
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^-]*)-([^-]*)$ $1_$2
RewriteRule ^([^-]*)-([^-]*)-([^-]*)$ $1_$2_$3

# make it so files with underscores that do exist explicitely redirect to files with slashes
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^([^_]*)_([^_]*)$ /$1-$2 [L,R=301]
RewriteRule ^([^_]*)_([^_]*)_([^_]*)$ /$1-$2-$3 [L,R=301]

他们自己工作但是一起导致无限循环。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

因为URI被重写然后重新插入重写引擎,你会得到一个重定向循环。您必须通过匹配请求而不是URI来进行外部重定向。此外,重写条件仅适用于紧随其后的重写规则,因此您需要为每个规则复制它们:

# make it so files with slashes that don't exist transparently redirect to files with underscores
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^-]*)-([^-]*)$ $1_$2 [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^-]*)-([^-]*)-([^-]*)$ $1_$2_$3 [L]

# make it so files with underscores that do exist explicitely redirect to files with slashes
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^_]*)_([^_]*)_([^_\ \?]*)
RewriteRule ^ /%1-%2-%3 [L,R=301]

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^_]*)_([^_\ \?]*)
RewriteRule ^ /%1-%2 [L,R=301]

答案 1 :(得分:1)

这真是一个有趣的问题。

我建议的代码是基于递归的通用代码,它会在网址中将每个_翻译成-(无论有多少下划线)。在内部,它将执行反向转换并加载实际的URL。

# Only single underscore do an external 301 redirect
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+([^_]+)_([^_\s]*) [NC]
RewriteRule ^ /%1-%2 [R=301,L]

# Recursively translate each _ to - in URL and do external 302 redirect
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+([^_]+)_([^\s]*) [NC]
RewriteRule ^ /%1-%2 [R,L]

# Recursively translate - to _ to load actual URL internally
RewriteRule ^([^-]+)-(.*)$ /$1_$2 [L]