问题描述
目前似乎是的mod_rewrite
线程左右浮动,最近有一些混乱了如何某些方面它的工作体面一些。这样一来,我编了几个音符上常见的功能,也许一些恼人的细微差别。
还有什么其他功能/常见的问题有您使用各地执行的mod_rewrite
?
在哪里放置mod_rewrite规则
的mod_rewrite
的规则可以放在的httpd.conf
文件中,或者在的.htaccess
文件。如果你有机会获得的httpd.conf
,这里将规则将提供一个性能优势(因为规则处理一次,而不是每次的.htaccess
文件被调用)。
日志mod_rewrite的请求
日志可以从的httpd.conf
文件中启用(包括<虚拟主机>
):
#日志不能从的.htaccess启用
#日志级别> 2,真是垃圾!
RewriteLog /path/to/rewrite.log
RewriteLogLevel 2
通用用例
-
漏斗所有请求到一个点:
RewriteEngine叙述上 #忽略现有文件 的RewriteCond%{} REQUEST_FILENAME!-f #忽略现有的目录 的RewriteCond%{} REQUEST_FILENAME!-d #请求映射到index.php文件并追加作为查询字符串 重写规则^(。*)$的index.php?查询= $ 1
因为Apache 2.2.16,你也可以使用
FallbackResource
。 -
办理301/302重定向:
RewriteEngine叙述上 #302重定向 重写规则^ oldpage \ html的$ /newpage.html [R = 302] #301重定向 重写规则^ oldpage2 \ html的$ /newpage.html [R = 301]
注意的:外部重定向隐含302重定向:
#这条规则: 重写规则^ SomePage的\ html的$ http://google.com #相当于: 重写规则^ SomePage的\ html的$ http://google.com [R] # 和: 重写规则^ SomePage的\ html的$ http://google.com [R = 302]
-
强制SSL
RewriteEngine叙述上 的RewriteCond%{} SERVER_PORT 80 重写规则^(。*)$ https://example.com/$1 [R,L]
-
常见标志使用的:
-
[R]
强制重定向(默认302) -
[R = 301]
迫使301重定向 -
[L]
停止重写的过程(参见下面的注释中常见的陷阱) -
[NC]
区分大小写的匹配
您可以混合和匹配标志:
重写规则^ olddir(。*)$ / NEWDIR $ 1 [L,NC]
-
常见的问题
-
混合
mod_alias中
风格重定向与的mod_rewrite
#错误 重定向302 /somepage.html http://example.com/otherpage.html RewriteEngine叙述上 重写规则^(。*)$的index.php?查询= $ 1 #好(使用mod_rewrite为) RewriteEngine叙述上 #302重定向并停止处理 重写规则^ somepage.html $ /otherpage.html [R = 302,L] 的RewriteCond%{} REQUEST_FILENAME!-f 的RewriteCond%{} REQUEST_FILENAME!-d #处理其他重定向 重写规则^(。*)$的index.php?查询= $ 1
注意的:你可以混合
mod_alias中
与的mod_rewrite
,但它涉及更多的工作不仅仅是处理基本重定向如上。 -
环境影响语法
在
的.htaccess
文件,一个领先的斜杠没有在该模式中使用:#给出:GET /directory/file.html #的.htaccess #结果:/newdirectory/file.html 重写规则^目录(。*)$ / newdirectory $ 1 #的.htaccess #结果:不匹配! 重写规则^ /目录(。*)$ / newdirectory $ 1 #的httpd.conf #结果:/newdirectory/file.html 重写规则^ /目录(。*)$ / newdirectory $ 1 #工程在两种情况下: 重写规则^ /?目录(。*)$ / newdirectory $ 1
-
[L]不上! (有时)
在
的.htaccess
范围内,[L]不会强迫的mod_rewrite
停止。它将继续触发内部子请求:#处理并不仅止于此 重写规则^ DIRA $ / DIRB [L] #/ DIRC将是最终的结果 重写规则^ DIRB $ / DIRC
我们的重写日志显示的详细信息:
改写迪拉 - > / DIRB 内部重定向与/ DIRB [内部重定向] 重写DIRB - > / DIRC
在这种情况下,
[结束]
应使用而不是[L]
。
There seem to be a decent number of mod_rewrite
threads floating around lately with a bit of confusion over how certain aspects of it work. As a result I've compiled a few notes on common functionality, and perhaps a few annoying nuances.
What other features / common issues have you run across using mod_rewrite
?
Where to place mod_rewrite rules
mod_rewrite
rules may be placed within the httpd.conf
file, or within the .htaccess
file. if you have access to httpd.conf
, placing rules here will offer a performance benefit (as the rules are processed once, as opposed to each time the .htaccess
file is called).
Logging mod_rewrite requests
logging may be enabled from within the httpd.conf
file (including <Virtual Host>
):
# logs can't be enabled from .htaccess
# loglevel > 2 is really spammy!
RewriteLog /path/to/rewrite.log
RewriteLogLevel 2
Common use cases
to funnel all requests to a single point:
RewriteEngine on # ignore existing files RewriteCond %{REQUEST_FILENAME} !-f # ignore existing directories RewriteCond %{REQUEST_FILENAME} !-d # map requests to index.php and append as a query string RewriteRule ^(.*)$ index.php?query=$1
Since Apache 2.2.16 you can also use
FallbackResource
.handling 301/302 redirects:
RewriteEngine on # 302 Redirect RewriteRule ^oldpage\.html$ /newpage.html [R=302] # 301 Redirect RewriteRule ^oldpage2\.html$ /newpage.html [R=301]
note: external redirects are implicitly 302 redirects:
# this rule: RewriteRule ^somepage\.html$ http://google.com # is equivalent to: RewriteRule ^somepage\.html$ http://google.com [R] # and: RewriteRule ^somepage\.html$ http://google.com [R=302]
forcing SSL
RewriteEngine on RewriteCond %{SERVER_PORT} 80 RewriteRule ^(.*)$ https://example.com/$1 [R,L]
common flag usage:
[R]
force a redirect (default 302)[R=301]
force a 301 redirect[L]
stop rewriting process (see note below in common pitfalls)[NC]
case insensitive matches
you can mix and match flags:
RewriteRule ^olddir(.*)$ /newdir$1 [L,NC]
Common pitfalls
mixing
mod_alias
style redirects withmod_rewrite
# Bad Redirect 302 /somepage.html http://example.com/otherpage.html RewriteEngine on RewriteRule ^(.*)$ index.php?query=$1 # Good (use mod_rewrite for both) RewriteEngine on # 302 redirect and stop processing RewriteRule ^somepage.html$ /otherpage.html [R=302,L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d # handle other redirects RewriteRule ^(.*)$ index.php?query=$1
note: you can mix
mod_alias
withmod_rewrite
, but it involves more work than just handling basic redirects as above.context affects syntax
within
.htaccess
files, a leading slash is not used in the pattern:# given: GET /directory/file.html # .htaccess # result: /newdirectory/file.html RewriteRule ^directory(.*)$ /newdirectory$1 # .htaccess # result: no match! RewriteRule ^/directory(.*)$ /newdirectory$1 # httpd.conf # result: /newdirectory/file.html RewriteRule ^/directory(.*)$ /newdirectory$1 # Works in both contexts: RewriteRule ^/?directory(.*)$ /newdirectory$1
[L] is not last! (sometimes)
within the
.htaccess
context, [L] will not forcemod_rewrite
to stop. it will continue to trigger internal sub-requests:# processing does not stop here RewriteRule ^dirA$ /dirB [L] # /dirC will be the final result RewriteRule ^dirB$ /dirC
our rewrite log shows the details:
rewrite 'dirA' -> '/dirB' internal redirect with /dirB [INTERNAL REDIRECT] rewrite 'dirB' -> '/dirC'
In such cases
[END]
should be used instead of[L]
.
这篇关于mod_rewrite的的隐藏功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!