求助:基于mod_rewrite实现指定URL重写及修复报错规则
关于mod_rewrite规则的求助
我已查阅相关问题及教程,但仍未完全理解mod_rewrite,故在此求助。当前我的.htaccess内容如下:
Options +FollowSymLinks RewriteEngine On #### 1st set of rules.... #### #Using THE_REQUEST for catching references and using them later on. RewriteCond %{THE_REQUEST} \s/(content)/index\.php\?var=(.*?)\s [NC] RewriteRule ^ /%1/featured/%2? [R=301,L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(content)/featured/(.*?)/?$ $1/index.php?var=$2 [QSA,NC,L] #### 2nd set of rules.... #### #Using THE_REQUEST for catching references and using them later on. RewriteCond %{THE_REQUEST} \s/(profile)\.php\?userid=(.*?)\s [NC] RewriteRule ^ /%1%2? [R=301,L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(profile)/(.*?)/?$ $1.php?userid=$2 [QSA,NC,L]
我需要实现将URL www.domain.com/content/cat/build 重写为 www.domain.com/content/catcontent.php?catvar=build,请问对应的mod_rewrite规则应该怎么写?
我曾尝试添加以下规则,但导致网站崩溃:
#### 3rd set of rules.... #### #Using THE_REQUEST for catching references and using them later on. RewriteCond %{THE_REQUEST} \s/(content)/(cat)/\catview\.php\?cattype=(.*?)\s [NC] RewriteRule ^ /%1%2? [R=301,L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(content)/(cat)/catview.php/?$ $1.php?cattype=$2 [QSA,NC,L]
我已通过谷歌搜索并查阅旧帖、教程,但仍觉得mod_rewrite晦涩难懂,恳请协助解决。
解决方案
先说说你之前尝试的问题
你写的第三组规则有几个明显错误:
- 正则里多了个多余的转义符:
\catview.php里的\是错的,应该直接写catview.php - 重定向目标路径错了:
/%1%2?会拼成/contentcat这种无意义的路径,缺了分隔符 - 内部重写的规则和目标不匹配:你要映射到的是
catcontent.php,但规则里写的是$1.php,对应成了content.php,完全不对
正确的规则写法
要实现 www.domain.com/content/cat/build → www.domain.com/content/catcontent.php?catvar=build,需要两套规则:一套把旧的动态URL跳转到友好URL(301重定向),另一套把友好URL内部转成动态文件(重写)
1. 301重定向(处理旧URL跳转)
如果有人访问旧的动态地址 content/catcontent.php?catvar=build,自动跳转到友好URL:
#### 3rd set of rules.... #### # 旧动态URL转友好URL RewriteCond %{THE_REQUEST} \s/content/catcontent\.php\?catvar=([^\s]+)\s [NC] RewriteRule ^ /content/cat/%1? [R=301,L]
2. 内部重写(处理友好URL)
把用户输入的友好URL悄悄转成实际的动态文件,用户看不到变化:
# 友好URL映射到实际文件 RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^content/cat/([^/]+)/?$ content/catcontent.php?catvar=$1 [QSA,NC,L]
整合后的完整.htaccess
把这部分规则加到你现有规则后面就行:
Options +FollowSymLinks RewriteEngine On #### 1st set of rules.... #### #Using THE_REQUEST for catching references and using them later on. RewriteCond %{THE_REQUEST} \s/(content)/index\.php\?var=(.*?)\s [NC] RewriteRule ^ /%1/featured/%2? [R=301,L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(content)/featured/(.*?)/?$ $1/index.php?var=$2 [QSA,NC,L] #### 2nd set of rules.... #### #Using THE_REQUEST for catching references and using them later on. RewriteCond %{THE_REQUEST} \s/(profile)\.php\?userid=(.*?)\s [NC] RewriteRule ^ /%1%2? [R=301,L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(profile)/(.*?)/?$ $1.php?userid=$2 [QSA,NC,L] #### 3rd set of rules.... #### # 旧动态URL转友好URL RewriteCond %{THE_REQUEST} \s/content/catcontent\.php\?catvar=([^\s]+)\s [NC] RewriteRule ^ /content/cat/%1? [R=301,L] # 友好URL映射到实际文件 RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^content/cat/([^/]+)/?$ content/catcontent.php?catvar=$1 [QSA,NC,L]
几个关键点解释
%{THE_REQUEST}用来抓实际的请求行,防止内部重写循环[R=301,L]是301永久重定向,L表示这条规则执行后就停了,不往下走[QSA]是保留额外的查询参数,比如访问content/cat/build?foo=bar会自动变成catcontent.php?catvar=build&foo=bar!-f和!-d是确保如果请求的是真实存在的文件或文件夹,就不执行重写,避免把图片、CSS这些静态资源搞乱
内容的提问来源于stack exchange,提问作者bobafart
相关产品推荐
相关产品推荐

