URL 重寫是將頁面映射到本站另一頁面, 而重定向則是將頁面映射到另一主機(域名). 其中臨時重定向(R=302)和永久重定向(R=301)都是親搜索引擎的, 是 SEO 的重要技術. 通過重定向, 瀏覽器和搜索引擎都意思到頁面發生了變化, 從而分別改變地址欄顯示的地址和更新搜索引擎索引。
Apache 中的 URL 重寫和重定向
AllowOverride all Options FollowSysLinks
開啟重寫日志
2.4 以下版本
RewriteLog "自定義日志路徑" # 設置日志等級 RewriteLogLevel 9
2.4 及其以上版本
LogLevel alert rewrite:trace3
注意: 日志級別越高, 越影響服務器性能. 生產環境下應關閉重寫日志.
重寫指令
RewriteEngine
RewriteEngine: 是否啟用重寫引擎. On啟用, Off不啟用.
RewriteBase
RewriteBase: 設置重寫的基準目錄. 基準目錄的根目錄就是網站的根目錄.
RewriteCond
RewriteCond: 設置重寫條件.
RewriteCond TestString CondPattern [flags]
RewriteCond 指令定義一條規則條件。
在一條 RewriteRule 指令前面可能會有一條或多條 RewriteCond 指令,只有 TestString 符合 CondPattern 時規則才被應用于當前URL處理。
1) TestString是一個純文本的字符串,除了包含普通的字符外,還可以包括下列的可擴展結構:
$N: RewriteRule 后向引用,其中(0 <= N <= 9) . $N引用緊跟在 RewriteCond 后面的 RewriteRule 中模板中的括號中的模板在當前 URL 中匹配的數據。
%N: RewriteCond 后向引用, 其中(0 <= N <= 9). %N引用最后一個 RewriteCond 的模板中的括號中的模板在當前 URL 中匹配的數據。
${mapname:key|default}:RewriteMap 擴展。
2) CondPattern是條件 pattern, 即一個應用于當前實例TestString 的正則表達式, 即 TestString 將會被計算然后與CondPattern 匹配. 作為一個標準的擴展正則式, CondPattern 有以下補充:
CondPattern中可以使用以下特殊變量:
>CondPattern: 大于, 將 CondPattern 當作一個普通字符串, 將它和 TestString 進行比較, 當T estString 的字符大于CondPattern 為真.=CondPattern: 等于, 將 CondPattern 當作一個普通字符串,將它和TestString進行比較, 當 TestString 與 CondPattern 完全相同時為真. 如果 CondPattern 只是 "" (兩個引號緊挨在一起) 此時需 TestString 為空字符串方為真
-d: 是否為目錄, 將 TestString 當作一個目錄名, 檢查它否存在以及是否是一個目錄.
-f: 是否是 regular file, 將 TestString 當作一個文件名, 檢查它是否存在以及是否是一個 regular 文件.
-s: 是否為長度不為0的 regular文件, 將 TestString 當作一個文件名, 檢查它是否存在以及是否是一個長度大于0的 regular 文件.
-l: 是否為 symbolic link, 將 TestString 當作一個文件名, 檢查它是否存在以及是否是一個 symbolic link.
-F: 通過 subrequest 來檢查某文件是否可訪問. 檢查 TestString 是否是一個合法的文件, 而且通過服務器范圍內的當前設置的訪問控制進行訪問. 這個檢查是通過一個內部 subrequest 完成的, 因此需要小心使用這個功能以降低服務器的性能.
-U: 通過 subrequest 來檢查某個 URL 是否存在. 檢查 TestString 是否是一個合法的URL, 而且通過服務器范圍內的當前設置的訪問控制進行訪問. 這個檢查是通過一個內部 subrequest 完成的, 因此需要小心使用這個功能以降低服務器的性能.
3) [flags]是第三個參數,多個標志之間用逗號分隔。
nocase|NC: 不區分大小寫. 在擴展后的 TestString 和 CondPattern 中, 比較時不區分文本的大小寫. 注意, 這個標志對文件系統和 subrequest 檢查沒有影響.
ornext|OR: 建立與下一個條件的或的關系. 默認的情況下,二個條件之間是AND的關系, 用這個標志將關系改為OR. 例如:
RewriteCond %{REMOTE_HOST} ^host1.* [OR] RewriteCond %{REMOTE_HOST} ^host2.* [OR] RewriteCond %{REMOTE_HOST} ^host3.* RewriteRule …
RewriteRule
RewriteRule: 設置重寫規則.
RewriteRule Pattern Substitution [flags].
1) Pattern是一個作用于當前 URL 的兼容 perl 的正則表達式. 這里的“當前”是指該規則生效時的 URL 的值。
2) Substitution是當原始 URL 與 Pattern 相匹配時, 用以替代(或替換)的字符串. (RewriteRule 中也會進行一次判斷, 被捕獲的 URL 是否與 Pattern相匹配)
3) Substitution還可以追加特殊標記[flags]作為 RewriteRule 指令的第三個參數。 Flags 是一個包含以逗號分隔的下列標記的列表:
強制性執行一個外部重定向. 如果code沒有指定, 則默認302. 如果需要使用在 300-400 范圍內的其他響應代碼, 只需在此指定這個數值即可。
另外, 還可以使用下列符號名稱之一: temp(默認的), permanent, seeother.
2.forbidden|F(強制 URL 為被禁止的 forbidden )
3.gone|G(強制 URL 為已廢棄的 gone )
11.qsappend|QSA(追加請求串 query string append)
此標記強制重寫引擎在已有的替換串中追加一個請求串, 而不是簡單的替換. 如果需要通過重寫規則在請求串中增加信息, 就可以使用這個標記。
12.noescape|NE(在輸出中不對URI作轉義 no URI escaping)
RewriteRule /foo/(.*) /bar?arg=P1=$1 [R,NE] 可以使’/foo/zed’轉向到一個安全的請求’/bar?arg=P1=zed’.
13.passthrough|PT(移交給下一個處理器 pass through)
14.skip|S=num(跳過后繼的規則 skip)
15.env|E=variable:value(設置環境變量 environment variable)
16.cookie|CO=NAME:VAL:domain[:lifetime[:path]](設置cookie)
在客戶端瀏覽器上設置一個cookie. cookie 的名稱是 NAME, 值是 VAL. domain字段是該 cookie 的域, 比如'.apache.org', 可選的 lifetime 是 cookie 生命期的分鐘數, 可選的 path 是 cookie 的路徑。
在.htaccess 文件中配置重寫規則
- 如果.htaccess在網站根目錄下, 那么RewriteRule捕獲的 URI 是subdir1/subdir2/subdir3.
- 如果.htaccess在 subdir1 目錄下, RewriteRule捕獲的 URI 是subdir2/subdir3.
RewriteRule重寫 URI 后的基準目錄也是以.htaccess所在的目錄為準. 例如: 訪問 http://example.com/foo
RewriteRule ^foo$ bar.php [L]
例1:
<IfModule mod_rewrite.c># 啟用rewrite引擎RewriteEngine On# 重寫規則: 匹配任意以htm后綴的文件, 將htm替換成php. ^(.*)\.htm$ 是一個正則表達式, 表示需要重寫的部分, 此處指以任意字符開頭, 以.htm結尾的部分. $1.php 是一個重寫規則, $1 表示匹配到正則表達式中第一個子模式的字符串. [NC]: 表示重寫規則如何應用, 該處表示不區分大小寫. 整條規則即重寫以任意字符開頭, 以.htm結尾的部分, 重寫為由匹配到的第一個子模式字符串和.php拼接成的字符串。RewriteRule ^(.*)\.htm$ $1.php [NC]</IfModule>
IfModule 命令用于判斷是否安裝了 mod_rewrite 模塊。
<IfModule mod_rewrite.c>RewriteEngine On# 設置目錄級重寫的基準URIRewriteBase /subdir1/RewriteRule ^(.*)\.htm$ $1.php [NC,L,R]</IfModule>
- RewriteBase設置了重寫的基準目錄. 如果上例中.htaccess位于網站根目錄下, 訪問的 http://example.com/foo.htm, 原本重寫后的基準目錄是網站根目錄/, 設置了RewriteBase后變為/subdir1/, 重寫后實際訪問 http://example.com/subdir1/foo.php.
- 規則標志L: 表示如果可以匹配本條規則, 則不再繼續往下匹配.
- 規則標志R: 表示臨時重定向, 即 302, 相當于[R=302]。
<IfModule mod_rewrite.c><IfModule mod_rewrite.c>RewriteEngine OnRewriteCond %{HTTP_HOST} (localhost:81)RewriteRule ^(.*) http://localhost:82 [R=301]</IfModule>
- [R=301]: 表示永久性重定向, 用戶發送的所有請求都會被發送到新域名處理,永久重定向到另一個域名使用了絕對 URI, 因此不用再設置 RewriteBase。
- %{HTTP_HOST}:表示引用 Apache 服務器變量 HTTP_HOST。
- 該條RewriteCond 表示判斷 HTTP_HOST 是否是 localhost:81。
在httpd.conf 中配置重寫規則
Nginx
Nginx 的 URL 重寫功能不需要額外的支持. Nginx 本身只支持在服務器配置文件中配置 URL 重寫規則, 不支持 .htaccess 文件. 但可以通過在服務器配置文件中引入外部文件的方式, 實現對 .htaccess 文件的支持. 這會嚴重影響 Nginx 的性能。
重寫指令
rewrite
rewrite regex replacement flag
- last: 相當于 Apache 中的L標記。
- break: 終止匹配, 不再匹配后面的規則。
- redirect: 臨時重定向, 返回 302。
- permanent: 永久性重定向, 返回 301。
rewrite ^(.*)\.html$ $1.php last;
if 指令
if (condition){...}
condition中可以包含如下判斷表示:
- ~: 區分大小寫進行匹配
- ~*: 不區分大小寫進行匹配
- !~: 區分大小寫進行非匹配
- !~*: 不區分大小寫進行非匹配
- -f: 如果文件存在
- !-f: 如果文件不存在
- -d: 如果目錄存在
- !-d: 如果目錄不存在
- -e: 如果文件或目錄存
- !-e: 如果文件或目錄不存在
- -x: 如果文件可執行
- !-x: 如果文件不可執行
location ~ \.html$ {if (!-f $request_filename){rewrite (.*)\.html$ $1.php last;}}
return 指令
return code復制代碼
return 403;
location 指令
location [flags] regex
flags 包括:
- ~: 執行一個正則匹配, 區分大小寫
- ~*: 執行一個正則匹配, 不區分大小寫
- ^~: 表示普通字符匹配. 使用前綴匹配成功. 如果匹配成功, 則不再匹配其他 location.
- =: 進行普通字符完全匹配.
- =的優先級最高. 匹配成功后, 不再匹配其他項.
- ^~類型表達式. 匹配成功后, 不再匹配其他項.
- ~和~*. 如果有多個 location 的正則匹配.
- 常規字符串匹配類型, 按前綴匹配.
rewrite_log 指令
rewrite_log on|off
set 指令
set variable value
Nginx 內置的全局變量
$args: 這個變量等于請求行中的參數, 同 $query_string.- $content_length: 請求頭中的 Content-length 字段.
- $content_type: 請求頭中的 Content-Type 字段.
- $document_root: 當前請求在 root 指令中指定的值.
- $host: 請求主機頭字段,否則為服務器名稱.
- $http_user_agent: 客戶端 agent 信息.
- $http_cookie: 客戶端 cookie 信息.
- $limit_rate: 這個變量可以限制連接速率.
- $request_method: 客戶端請求的動作,通常為 GET 或 POST.
- $remote_addr: 客戶端的 IP 地址.
- $remote_port: 客戶端的端口.
- $remote_user: 已經經過 Auth Basic Module 驗證的用戶名.
- $request_filename: 當前請求的文件路徑, 由 root 或 alias 指令與 URI 請求生成.
- $scheme: HTTP 方法(如 http, https).
- $server_protocol: 請求使用的協議, 通常是HTTP/1.0 或 HTTP/1.1.
- $server_addr: 服務器地址, 在完成一次系統調用后可以確定這個值.
- $server_name: 服務器名稱.
- $server_port: 請求到達服務器的端口號.
- $request_uri: 包含請求參數的原始 URI, 不包含主機名, 如: ”/foo/bar.php?arg=baz”.
- $uri: 不帶請求參數的當前 URI, $uri 不包含主機名, 如 "/foo/bar.html".
- $document_uri: 與$uri相同.
掃碼二維碼 獲取免費視頻學習資料
- 本文固定鏈接: http://www.wangchenghua.com/post/7234/
- 轉載請注明:轉載必須在正文中標注并保留原文鏈接
- 掃碼: 掃上方二維碼獲取免費視頻資料