URL 重寫是將頁面映射到本站另外一頁面, 而重定向則是將頁面映射到另外一主機(域名). 其中臨時重定向(R=302)和永久重定向(R=301)都是親搜索引擎的, 是 SEO 的重要技術. 經過重定向, 瀏覽器和搜索引擎都意思到頁面發生了變化, 從而分別改變地址欄顯示的地址和更新搜索引擎索引。php
啓用Apache 的 URL 重寫功能, 須要開啓mod_rewrite模塊.。而後在服務器配置文件或htaccess中修改服務配置:html
AllowOverride all Options FollowSysLinks
服務器配置文件和htaccess文件中均可以配置 URL 重寫,前者是服務器級別, 後者是目錄級別。web
2.4 如下版本正則表達式
在Apache 服務器配置文件中追加:apache
`RewriteLog "自定義日誌路徑"
# 設置日誌等級
RewriteLogLevel 9`api
等級0 爲關閉, 9 表示輸出最詳細信息。瀏覽器
2.4 及其以上版本安全
在Apache 服務器配置文件中追加:服務器
LogLevel alert rewrite:trace3
cookie
其中trace3 能夠替換爲 trace1 到 trace8, 數值越大輸出的信息越詳細. 最後輸出的日誌信息在apache_error.log文件中.
注意: 日誌級別越高, 越影響服務器性能. 生產環境下應關閉重寫日誌.
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 有如下補充:
能夠在模板串前增長一個!前綴,以表示不匹配模板。但並非全部的 test 均可以加!前綴。
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 …
若是沒有[OR]標誌,須要寫三個條件/規則。
RewriteRule:設置重寫規則.
語法:
RewriteRule Pattern Substitution [flags].
1) Pattern是一個做用於當前 URL 的兼容 perl 的正則表達式. 這裏的「當前」是指該規則生效時的 URL 的值。
2) Substitution是當原始 URL 與 Pattern 相匹配時, 用以替代(或替換)的字符串. (RewriteRule 中也會進行一次判斷, 被捕獲的 URL 是否與 Pattern相匹配)
3) Substitution還能夠追加特殊標記[flags]做爲 RewriteRule 指令的第三個參數。 Flags 是一個包含以逗號分隔的下列標記的列表:
1.redirect|R[=code] (強制重定向 redirect)
強制性執行一個外部重定向. 若是code沒有指定, 則默認302. 若是須要使用在 300-400 範圍內的其餘響應代碼, 只需在此指定這個數值便可。
另外, 還可使用下列符號名稱之一: temp(默認的), permanent, seeother.
注意:在使用這個標記時,務必確保該替換字段是一個有效的 URL ! 而且要記住,若是但願中止重寫操做而當即重定向,則還須要使用L標記。
2.forbidden|F(強制 URL 爲被禁止的 forbidden )
強制當前URL 爲被禁止的, 當即反饋一個 403. 使用這個標記, 能夠連接若干 RewriteConds 以有條件地阻塞某些 URL。
3.gone|G(強制 URL 爲已廢棄的 gone )
強制當前URL 爲已廢棄的, 當即反饋一個 410. 使用這個標記, 能夠標明頁面已經被廢棄而不存在了。
4.proxy|P(強制爲代理 proxy )
此標記使替換成分被內部強制爲代理請求, 並當即(重寫規則處理當即中斷)把處理移交給代理模塊. 你必須確保此替換串是一個有效的, 可以爲 Apache 代理模塊所處理的 URI. 使用這個標記, 能夠把某些遠程成分映射到本地服務器名稱空間, 從而加強了 ProxyPass 指令的功能。
注意:要使用這個功能, 代理模塊必須編譯在Apache服務器中. 不能肯定, 能夠檢查httpd -l的輸出中是否有mod_proxy.c. 若是有, 則mod_rewrite可使用這個功能; 若是沒有, 則必須啓用mod_proxy並從新編譯httpd程序.
5.last|L(最後一個規則 last)
當即中止重寫操做, 並再也不應用其餘重寫規則. 它對應於 Perl中 的last命令或C語言中的break命令. 這個標記能夠阻止當前已被重寫的 URL 爲其後繼的規則所重寫.
6.next|N(從新執行 next round)
從新執行重寫操做(從第一個規則從新開始). 這時再次進行處理的URL已經不是原始的URL, 而是經最後一個重寫規則處理的URL. 它對應於 Perl 中的next命令或C語言中的continue命令. 此標記能夠從新開始重寫操做, 即當即回到循環的頭部.
7.chain|C(與下一個規則相連接 chained)
此標記使當前規則與下一個(其自己又能夠與其後繼規則相連接的, 並能夠如此反覆的)規則相連接. 它產生這樣一個效果: 若是一個規則被匹配, 一般會繼續處理其後繼規則, 即這個標記不起做用; 若是規則不能被匹配, 則其後繼的連接的規則會被忽略. 好比, 在執行一個外部重定向時, 對一個目錄級規則集, 你可能須要刪除".www" (此處不該該出現".www"的).
8.type|T=MIME-type(強制MIME類型 type)
強制目標文件的MIME 類型爲 MIME-type. 好比, 它能夠用於模擬 mod_alias 中的 ScriptAlias 指令, 在內部強制被映射目錄中的全部文件的 MIME 類型爲"application/x-httpd-cgi".
9.nosubreq|NS(僅用於不對內部子請求進行處理 no internal sub-request)
在當前請求是一個內部子請求時, 此標記強制重寫引擎跳過該重寫規則. 好比, 在 mod_include 試圖搜索可能的目錄默認文件(http://index.xxx)時, Apache 會在內部產生子請求. 對子請求, 它不必定有用的, 並且若是整個規則集都起做用, 它甚至可能會引起錯誤. 因此, 能夠用這個標記來排除某些規則.
10.nocase|NC(忽略大小寫 no case)
它使Pattern 忽略大小寫。
11.qsappend|QSA(追加請求串 query string append)
此標記強制重寫引擎在已有的替換串中追加一個請求串, 而不是簡單的替換. 若是須要經過重寫規則在請求串中增長信息, 就可使用這個標記。
12.noescape|NE(在輸出中不對URI做轉義 no URI escaping)
此標記阻止mod_rewrite 對重寫結果應用常規的 URI 轉義規則. 通常狀況下, 特殊字符(如%, $, ;等)會被轉義爲等值的十六進制編碼. 此標記能夠阻止這樣的轉義, 容許百分號等符號出如今輸出中,如:
RewriteRule /foo/(.*) /bar?arg=P1=$1 [R,NE] 可使’/foo/zed’轉向到一個安全的請求’/bar?arg=P1=zed’.
13.passthrough|PT(移交給下一個處理器 pass through)
讓mod_rewrite 模塊將重寫的 URL 傳回給 Apache 作進一步處理。
14.skip|S=num(跳事後繼的規則 skip)
若是知足某指定的條件,則跳事後面第num 調規則。
15.env|E=variable:value(設置環境變量 environment variable)
此標記使環境變量variable 的值爲 value, VAL能夠包含可擴展的反向引用的正則表達式$N和%N. 此標記能夠屢次使用以設置多個變量。這些變量能夠在後繼的 RewriteCond 指令的pattern 中經過%{ENV:VAR}做引用 。
16.cookie|CO=NAME:VAL:domain[:lifetime[:path]](設置cookie)
在客戶端瀏覽器上設置一個cookie. cookie 的名稱是 NAME, 值是 VAL. domain字段是該 cookie 的域, 好比'.apache.org', 可選的 lifetime 是 cookie 生命期的分鐘數, 可選的 path 是 cookie 的路徑。
在.htaccess文件中使用重寫功能時, RewriteRule 負責匹配的 URI 是相對.htaccess所在的目錄而言的。
例如訪問http://example.com/subdir1/su...:
RewriteRule重寫 URI 後的基準目錄也是以.htaccess所在的目錄爲準. 例如: 訪問 http://example.com/foo
RewriteRule ^foo$ bar.php [L]
若是.htaccess在根目錄下, 重寫後訪問 http://example.com/bar.php. 若是在 subdir1 目錄下, 重寫後訪問 http://example.com/subdir1/ba...
例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 模塊。
例2:
<IfModule mod_rewrite.c>RewriteEngine On# 設置目錄級重寫的基準URIRewriteBase /subdir1/RewriteRule ^(.*)\.htm$ $1.php [NC,L,R]</IfModule>
例3:
<IfModule mod\_rewrite.c><IfModule mod\_rewrite.c>RewriteEngine OnRewriteCond %{HTTP\_HOST} (localhost:81)RewriteRule ^(.\*) http://localhost:82 \[R=301\]</IfModule>
在服務器配置文件中配置URL 重寫的指令與 .htaccess 文件中的格式相同,須要寫在<Directory>內.
Nginx 的 URL 重寫功能不須要額外的支持. Nginx 自己只支持在服務器配置文件中配置 URL 重寫規則, 不支持 .htaccess 文件. 但能夠經過在服務器配置文件中引入外部文件的方式, 實現對 .htaccess 文件的支持. 這會嚴重影響 Nginx 的性能。
rewrite
根據重寫規則, 重寫 URL。
語法:
rewrite regex replacement flag
應用環境: server, location, if
可應用的flag 標記包括:
示例:
rewrite ^(.*)\.html$ $1.php last;
注意:若是訪問的是 http://localhost/dir/file, rewrite 中的正則表達式匹配的是 /dir/file, 包括最左邊的正斜槓.
語法:
if (condition){...}
注意if以後緊跟的空格不能省略。
應用環境:server, location
判斷一個條件是否符合, 若是符合, 則執行大括號內語句. if 指令不支持嵌套, 不支持&&和||操做。
condition中能夠包含以下判斷表示:
示例:
location ~ \.html$ {if (!\-f $request_filename){rewrite (.*)\.html$ $1.php last;}}
訪問的URL 以.html結尾時, 判斷是否存在該文件, 若是不存在就重寫爲訪問同名的 PHP 腳本。
語法:
return code複製代碼
應用環境:server, location, if
該指令用於結束規則的執行並返回狀態碼給客戶端。
例如:
return 403;
語法:
location [flags] regex
應用環境: server
flags 包括:
優先級:
語法:
rewrite_log on|off
應用環境:server, location, if
啓用時, 將在error_log中記錄 notice 級別的重寫日誌.
語法:
set variable value
應用環境:server, location, if
爲給定的變量設置一個特定值。
$args: 這個變量等於請求行中的參數, 同 $query_string.