mod_rewrite的的隐藏功能 [英] Hidden features of mod_rewrite

查看:264
本文介绍了mod_rewrite的的隐藏功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前似乎是的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
 

通用用例

  1. 漏斗所有请求到一个点:

      RewriteEngine叙述上
    #忽略现有文件
    的RewriteCond%{} REQUEST_FILENAME!-f
    #忽略现有的目录
    的RewriteCond%{} REQUEST_FILENAME!-d
    #请求映射到index.php文件并追加作为查询字符串
    重写规则^(。*)$的index.php?查询= $ 1
     

    因为Apache 2.2.16,你也可以使用 FallbackResource

  2. 办理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]
     

  3. 强制SSL

      RewriteEngine叙述上
    的RewriteCond%{} SERVER_PORT 80
    重写规则^(。*)$ https://example.com/$1 [R,L]
     

  4. 常见标志使用的:

    • [R] 强制重定向(默认302)
    • [R = 301] 迫使301重定向
    • [L] 停止重写的过程(参见下面的注释中常见的陷阱)
    • [NC] 区分大小写的匹配

    您可以混合和匹配标志:

     重写规则^ olddir(。*)$ / NEWDIR $ 1 [L,NC]
     

常见的问题

  1. 混合 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 ,但它涉及更多的工作不仅仅是处理基本重定向如上。

  2. 环境影响语法

    的.htaccess 文件,一个领先的斜杠没有在该模式中使用:

     #给出:GET /directory/file.html
    
    #的.htaccess
    #结果:/newdirectory/file.html
    重写规则^目录(。*)$ / newdirectory $ 1
    
    #的.htaccess
    #结果:不匹配!
    重写规则^ /目录(。*)$ / newdirectory $ 1
    
    #的httpd.conf
    #结果:/newdirectory/file.html
    重写规则^ /目录(。*)$ / newdirectory $ 1
    
    #工程在两种情况下:
    重写规则^ /?目录(。*)$ / newdirectory $ 1
     

  3. [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

  1. 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.

  2. 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]
    

  3. forcing SSL

    RewriteEngine on
    RewriteCond %{SERVER_PORT} 80
    RewriteRule ^(.*)$ https://example.com/$1 [R,L]
    

  4. 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

  1. mixing mod_alias style redirects with mod_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 with mod_rewrite, but it involves more work than just handling basic redirects as above.

  2. 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
    

  3. [L] is not last! (sometimes)

    within the .htaccess context, [L] will not force mod_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的的隐藏功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆