什么是URL重定向:
URL重定向(URL redirection,或稱網址重定向或網域名稱轉址),是指當使用者瀏覽某個網址時,將他導向到另一個網址的技術。
重寫和重定向的區別:
重定向 :瀏覽器知道頁面位置發生變化,從而改變地址欄顯示的地址
搜索引擎意識到頁面被移動了,從而更新搜索引擎索引,將原來失效的鏈接從搜索結果中移除
臨時重定向(R=302)和永久重定向(R=301)都是親搜索引擎的,是SEO的重要技術
重寫:用於將頁面映射到本站另一頁面,若重寫到另一網絡主機(域名),則按重定向處理
URL重定向模塊開啟:
如果要想用到rewrite模塊,必須先安裝或加載rewrite模塊。
方法有兩種
一種是編譯apache的時候就直接安裝rewrite模塊,
二是如果編譯apache時以DSO模式安裝apache的,可以利用源碼和apxs來安裝rewrite模塊。
URl重定向配置方式:
1.可基於服務器級
1.1 (httpd.conf),在httpd.conf中寫,這種寫法適合有服務器完整權限的網站管理員,
RewriteEngine on來打開rewrite功能;
1.2 另一種是在局部virtualhost里 利用RewriteEngine on來打開rewrite功能,
需要注意的是,必須在每個virtualhost里用RewriteEngine on來打開rewrite功能。
否則virtualhost里沒有RewriteEngine on它里面的規則也不會生效。
寫法大概如下:
<VirtualHost *:80>
DocumentRoot "/websites/www"
ServerName localhost
RewriteEngine On
RewriteRule ^index\.html$ index.php [L]
</VirtualHost>
2.目錄級
(.htaccess)在網站目錄中使用.htaccess,這種方法適合采用虛擬主機形式的網站管理員,
.htaccess文件可以的事情,主要包括:文件夾密碼保護、用戶自定義重定向、自定義404頁面、擴展名偽靜態化、禁止特定IP地址的用戶、只允許特定IP地址的用戶、禁止目錄列表,等等。
修改這個配置: AllowOverride None(修改為AllowOverride All)
要注意一點那就是必須打開此目錄的FollowSymLinks 符號鏈接屬性,且在.htaccess里要聲明RewriteEngine on
一些我們需要注意的地方:
FollowSymlinks必須啟用,這是rewrite引擎的安全需求。
通常FollowSymlinks在Apache的主配置文件中就已經啟用了,所以通常可以省略。
RewriteEngine命令用於啟用rewrite引擎
IfModule命令用於判斷Apache是否安裝了mod_rewrite模塊
mod_rewrite會處理所有提交給Apache的URL請求,並與之后的規則進行匹配
基本正則表達式:
因為URL重定向語法中大量使用了perl的正則表達式,並且正則是每隔一段時間不用都必然會淡忘的東西,所以我們有必要先回顧一下基本的正則寫法:
. 匹配一個字符,(范圍是換行符以外的所有字符)
\w 匹配字母或數字或下划線或漢字
\s 匹配任意的空白符
\d 匹配數字
\b 匹配單詞的開始或結束
^ 字符串以……開始
$ 字符串以……結束
* 重復零次或更多次
+ 重復一次或更多次
? 重復零次或一次
{n} 重復n次
{n,} 重復n次或更多次
{n,m} 重復n到m次
() $1 $2 一個括號代表一個分組,第一個括號里匹配的內容就用$1引用,第二個括號匹配的內容用$2引用,以此類推......
指令講解:
1.重寫規則的指令:
對於Rewrite來說共有九個指令:
RewriteBase,
RewriteCond,
RewriteEngine,
RewriteLock,
RewriteLog,
RewriteLogLevel,
RewriteMap,
RewriteOptions,
RewriteRule。
通常最常用的是 RewriteEngine, RewriteBase, RewriteCond, RewriteRule 四個指令,
下面簡單介紹這四個指令。
RewriteEngine: 就是是否使用 Rewrite 模式的開關, 使用就設置成 on, 否則設置成 off。
RewriteBase:設置了目錄級重寫的基准URL,RewriteBase 的作用域為: directory, .htaccess
多數網站URL不是直接對應於其物理文件路徑的,在這種情況下,
就必須用RewriteBase指令來指定正確的URL前綴。
通常默認的虛擬主機的網站在使用.htaccess 進行重寫規則時不需要執行設置該指令.
因為 RewriteBase 默認值是該 .htaccess 文件所在的目錄地址.
但是如果使用目錄別名的話就需要設置這個指令了,例如 alias
舉個例子,如果將1.html 重定向為1.php 設置為 RewriteBase /base/,
那么將會重定向到http://yourdomain.com/base/1.php。
對於重寫基准目錄,我們還可以通過將$1.php變成/$1.php實現直接變換,這時就可以將RewriteBase省略。
如果重定向到新的主機地址(域名),RewriteBase也就沒有出現的必要了。
RewriteCond:指令定義一條規則條件。
在一條RewriteRule指令前面可能會有一條或多條RewriteCond指令,
只有當自身的模板(pattern)匹配成功且這些條件也滿足時規則才被應用於當前URL處理。
注意,RewriteCond 指令后面可帶 Flag, 現在只要2個可用,
一個是 NC(不區分大小寫的意思), 一個是 OR(連接下一個條件)。
RewriteRule:是一個簡單的命令告訴mod_rewrite這個模塊如何去重寫,
關鍵的地方在於可以在模式和替換中使用正則表達式來匹配相應的字符,
正則表達式的廣泛的靈活性能將動態的URL轉換成各式各樣的符合要求的靜態URL
格式: RewriteRule Pattern Substitution [flags]
在URL重寫的匹配部分中, 服務器會把請求的URL的一部分刪除掉,再傳遞給Pattern部分進行匹配.
重寫結束后再添加上去.
所有平常我們看到的匹配規則總是不帶網址前面的那些域名的什么東西的. 也不帶什么目錄什么的.
這些 apache已經給刪掉了. 處理完后再加到前面。
但是有個例外就是如果 Substitution 部分是帶 http:// 開頭的話, 那就直接重定向了. 服務器不會把先前刪除的再給加上了. 不然就出錯了。
Apache Rewrite規則修正符 :
R 強制外部重定向 redirect|R [=code] (強制重定向 redirect)
例如: [R=301,L] 永久重定向; [R=302,L] 臨時重定向;R默認為302
F 禁用URL,返回403HTTP狀態碼。
G 強制URL為GONE,返回410HTTP狀態碼。
P 強制使用代理轉發。
L 表明當前規則是最后一條規則,停止分析以后規則的重寫。
N 重新從第一條規則開始運行重寫過程。
C 與下一條規則關聯
2.服務器變量
NAME_OF_VARIABLE 具體數值見下表:
HTTP_USER_AGENT //主要用於檢測訪問者系統和瀏覽器等
HTTP_REFERER //從哪個頁面鏈接過來
HTTP_COOKIE
HTTP_FORWARDED
HTTP_HOST //取請求的域名 例如:www.test.com;不包括“http://”和“ /”
REQUEST_URI //這是在HTTP請求行中所請求的資源。例如:/share77.html
相對地址,就是相對根目錄的地址,就是域名/后面的成分,格式上包括最前面的“/”
REQUEST_FILENAME //這是與請求相匹配的完整的本地文件系統的文件路徑名或描述.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
這兩句語句的意思是請求的文件或路徑是不存在的,
如果文件或路徑存在將返回已經存在的文件或路徑
HTTP_PROXY_CONNECTION
HTTP_ACCEPT
REMOTE_ADDR
REMOTE_HOST
REMOTE_USER
REMOTE_IDENT
REQUEST_METHOD
SCRIPT_FILENAME
PATH_INFO
QUERY_STRING
AUTH_TYPE
DOCUMENT_ROOT
SERVER_ADMIN
SERVER_NAME
SERVER_ADDR
SERVER_PORT
SERVER_PROTOCOL
SERVER_SOFTWARE
TIME_YEAR
TIME_MON
TIME_DAY
TIME_HOUR
TIME_MIN
TIME_SEC
TIME_WDAY
TIME
API_VERSION //這是正在使用的httpd中(服務器和模塊之間內部接口)的Apache模塊API的版本,
其定義位於include/ap_mmn.h中。此模塊版本對應於正在使用的Apache的版本
(比如,在Apache 1.3.14的發行版中,這個值是19990320:10)。
通常,對它感興趣的是模塊的作者。
THE_REQUEST //這是由瀏覽器發送給服務器的完整的HTTP請求行。
(比如, “GET /index.html HTTP/1.1″). 它不包含任何瀏覽器發送的附加頭信息。
IS_SUBREQ //如果正在處理的請求是一個子請求,它包含字符串”true”,否則就是”false”。
模塊為了解析URI中的附加文件,有可能會產生子請求。
實例分析:
1.重寫,只對域名后的資源進行修改
RewriteRule ^/$ /about/ [R]
http://www.xxx.cn/index.html -> http://www.xxx.cn/index.php
RewriteRule index.html index.php
http://www.xxx.cn/test8.html -> http://www.xxx.cn/test.php?id=8 (這個也叫偽靜態)
RewriteRule ^test([0-9]*).html$ test.php?id=$1
http://www.xxx.cn/cat-1-3.html -> http://www.xxx.cn/cat.php?id1=1&id2=3
RewriteRule ^cat-([0-9]+)-([0-9]+)\.html$ cat.php?id1=$1&id2=$2
前面第一個()中匹配的內容后面就用$1引用,第二個()中匹配的就用$2應用……
將.htm頁面映射到.php:
RewriteRule ^(.*)\.htm$ $1.php [NC]
注意事項:
該RewriteRule能夠將.htm靜態頁面映射到.php動態頁面
如果通過.htm進入,瀏覽器地址欄顯示的是.htm擴展名,但服務器上實際執行的是.php
[NC]表示“不區分大小寫”
增加一個R標識符,重寫即變為重定向:
RewriteRule ^(.*)\.htm$ $1.php [R,NC,L]
注意事項:
該RewriteRule能夠將.htm靜態頁面重定向到.php動態頁面
如果通過.htm進入,瀏覽器地址欄會自動轉為.php,這也是重定向的本質
2..基於域名的重定向
當訪問163.com時 跳轉到www.163.com
RewriteCond %{HTTP_HOST} ^163.com [NC]
RewriteRule ^(.*) http://www.163.com$1 [R=301,L]
當訪問這個70.40.213.183 開頭的ip時,跳轉到www.163.com域名
RewriteCond %{HTTP_HOST} ^70.40.213.183 [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteRule ^(.*) http://www.163.com/ [L]
#聲明Client請求的主機中前綴是70.40.213.183, [NC] 的意思是忽略大小寫
#聲明Client請求的主機中前綴不為空
#[L]意味着立即停止重寫操作,並不再應用其他重寫規則。
。
又跨域,又要url不變的重定向
我們可以用以下方法解決:(這樣瀏覽器中的url沒有變化 , 但是內容已經是sina的了)
RewriteRule /66.htm$ http://www.sina.com.cn [P]
RewriteRule /66.htm$ http://127.0.0.1:8080/sohu/sd.jsp [P]
注意:這里的P是代理模式轉發,必須用url全稱,並且要保證modProxy打開,也就是下面httpd.conf中的着兩句:
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
如果不打開則會出現403禁止頁面。
1、圖片重定向
RewriteEngine On
RewriteCond %{HTTP_HOST} ^localhost$ //如果域名是localhost
RewriteCond %{REQUEST_FILENAME} !-f //並且訪問的文件找不到
RewriteRule ^images/(.+) http://127.0.0.1/test/showimages/$1 [R=302,L]
//則跳轉到另一個域名下的另一個目錄訪問這個圖片
當請求不存在的資源時, 統一定義到根目錄下的 404.html
文件名不存在、目錄不存在、跳轉404頁面
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /404.html [L]
限制訪問. 比如來自一些不友好的網站連接過來的請求. 不允許訪問.
下例中如果 HTTP_REFERER 中包含 sex 字符, 則不允許訪問.
RewriteCond %{HTTP_REFERER} sex
RewriteRule ^.*$ - [F]
偽靜態化, 比如訪問 /user20.html 則調用viewUser.php 顯示用戶ID為20的用戶資料
RewriteRule ^user([0-9]*)\.html$ viewUser.php?userid=$1
喜歡用二級域名的比較實用了. 比如網站目錄下有 user, upload 等幾個目錄,
可以通過 http://www.test.com/user 這樣的模式訪問.
但是如果想做成統一用二級域名模式訪問: http://user.test.com , 但是不允許 http://www.test.com/user 這樣訪問.
那么就像下面這樣來限制.
RewriteCond %{REQUEST_URI} ^/user
RewriteRule ^.*$ http://user.test.net" [L]
防止圖片盜鏈
RewriteEngine On
RewiteBase /
RewriteCond %{HTTP_REFERER} !^http://(.+.)?baidu.com/ [NC] //如果來源網址不是*.baidu.com
RewriteCond %{HTTP_REFERER} !^$ //並且來源網址不是空
RewriteRule .*.(jpe?g|gif|bmp|png)$ /images/nohotlink.jpg [L] //如果訪問的文件后綴是jpeg,jpg,gif,bmp,png的圖片,則重定向到一個固定的圖片
我們使用 .htaccess 來定義重寫規則. 假設域名為: www.test.com
.htaccess 放在網站根目錄下. 比如: /.htaccess
例子1: 所有請求都定向到 index.php 腳本, 注意要排除 index.php 本身. 比如就進入死循環了.
RewriteRule !^index\.php$ index.php [L]
例子2: 按照時間顯示不同的頁面, 比如訪問 hello.html 頁面時.
如果 在 8:00-19:00 的時候訪問. 顯示 hello.day.html 其他時間訪問顯示: hello.night.html
RewriteCond %{TIME_HOUR}%{TIME_MIN} >0700
RewriteCond %{TIME_HOUR}%{TIME_MIN} <1900
RewriteRule ^hello\.html$ hello.day.html
RewriteRule ^hello\.html$ hello.night.html
官方的例子: 重寫規則寫在 httpd.conf 文件里. 請求地址為: http://www.test.com/somepath/pathinfo,
看下面幾種結果. Given Rule => Resulting Substitution
-------------------------------------------------------------------------------
^/somepath(.*) otherpath$1 => 不支持, 無效的重寫語句
^/somepath(.*) otherpath$1 [R] => 不支持, 無效的重寫語句
^/somepath(.*) otherpath$1 [P] => 不支持, 無效的重寫語句
-------------------------------------------------------------------------------
^/somepath(.*) /otherpath$1 => /otherpath/pathinfo
^/somepath(.*) /otherpath$1 [R] => http://www.test.com/otherpath/pathinfo 外部重定向
^/somepath(.*) /otherpath$1 [P] => 不支持, 很傻.
-------------------------------------------------------------------------------
^/somepath(.*) http://www.test.com/otherpath$1 => /otherpath/pathinfo
^/somepath(.*) http://www.test.com/otherpath$1 [R] => http://www.test.com/otherpath/pathinfo 外部重定向
^/somepath(.*) http://www.test.com/otherpath$1 [P] => 不支持, 很傻.
---------------------------------------------- ----------------------------------
^/somepath(.*) http://www.xxx.com/otherpath$1 => http://www.xxx.com/otherpath/pathinfo 外部重定向
^/somepath(.*) http://www.xxx.com/otherpath$1 [R] => http://www.xxx.com/otherpath/pathinfo 外部重定向 [R] 多余.
^/somepath(.*) http://www.xxx.com/otherpath$1 [P] => http://www.xxx.com/otherpath/pathinfo 內部網關重定向
同樣的請求上面的地址, 如果在 .htaccess 文件里的寫法. 注意和 httpd.conf 寫法的區別.
比如 .htaccess 文件在目錄一個虛擬主機的根目錄下.
然后請求 http://www.test.com/localpath/pathinfo 看下面的幾種結果.
Given Rule => Resulting Substitution
-------------------------------------------------------------------------------
^localpath(.*) otherpath$1=> /otherpath/pathinfo
^localpath(.*) otherpath$1 [R] => http://www.test.com/otherpath/pathinfo 外部重定向
^localpath(.*) otherpath$1 [P] => 不支持, 很傻.
-------------------------------------------------------------------------------
^localpath(.*) /otherpath$1 => /otherpath/pathinfo 注意 /otherpath$1 和 otherpath$1 的區別
^localpath(.*) /otherpath$1 [R] => http://www.test.com/otherpath/pathinfo 外部重定向
^localpath(.*) /otherpath$1 [P] => 不支持, 很傻.
-------------------------------------------------------------------------------
^localpath(.*) http://www.test.com/otherpath$1 /otherpath/pathinfo
^localpath(.*) http://www.test.com/otherpath$1 [R] http://www.test.com/otherpath/pathinfo 外部重定向
^localpath(.*) http://thishost/otherpath$1 [P] => 不支持, 很傻.
-------------------------------------------------------------------------------
^localpath(.*) http://www.test.com/otherpath$1 => http://www.test.com/otherpath/pathinfo 外部重定向
^localpath(.*) http://www.xxx.com/otherpath$1 [R] => http://www.xxx.com/otherpath/pathinfo 外部重定向 [R] 可省略
^localpath(.*) http://www.xxx.com/otherpath$1 [P] => http://www.xxx.com/otherpath/pathinfo 內部網關重定向
Apache重寫規則的常見應用(rewrite)
一:目的
本文旨在提供怎么用Apache重寫規則來解決一些常見的URL重寫方法的問題,通過常見的
實例給用戶一些使用重寫規則的基本方法和線索。
二:為什么需要用重寫規則?
一個網站,如果是長期需要放在internet上提供服務,必定會有不斷地更新和維護,如臨
時轉移到其他服務器進行維護,重新組織目錄結構,變換URL甚至改動到新的域名等等,
而為了讓客戶不會因此受到所有影響,最佳的方法就是使用Apache Rewrite Rule(重寫
規則)。
三: 重寫規則的作用范圍
1) 能使用在Apache主設置文件httpd.conf中
2) 能使用在httpd.conf里定義的虛擬主機設置中
3) 能使用在基本目錄的跨越設置文件.htaccess中
四:重寫規則的應用條件
只有當用戶的WEB請求最終被導向到某台WEB服務器的Apache后台,則這台WEB服務器接受
進來的請求,根據設置文件該請求是主設置還是虛擬主機,再根據用戶在瀏覽器中請求的
URI來配對重寫規則並且根據實際的請求路徑配對.htaccess中的重寫規則。最后把請求
的內容傳回給用戶,該響應可能有兩種:
1) 對瀏覽器請求內容的外部重定向(Redirect)到另一個URL。
讓瀏覽器再次以新的URI發出請求(R=301或R=302,臨時的或是永久的重定向)
如:一個網站有正規的URL和別名URL,對別名URL進行重定向到正規URL,或網站改換
成了新的域名
則把舊的域名重定向到新的域名(Redirect)
2) 也可能是由Apache內部子請求代理產生新的內容送回給客戶[P,L]
這是Apache內部根據重寫后的URI內部通過代理模塊請求內容並送回內容給客戶,而客戶
端瀏覽器並不知道,瀏覽器中的URI不會被重寫。但實際內容被Apache根據重寫規則后的URI得到。
如:在公司防火牆上運行的Apache啟動這種代理重寫規則,代理對內部網段上的WEB服務
器的請求。
五:重寫規則怎樣工作?
我們假定在編譯Apache時已把mod_rewrite編譯成模塊,確信你的httpd.conf中有
LoadModule rewrite_module libexec/mod_rewrite.so
並且在Addmodule中有 Addmodule mod_rewrite.c則能使用重寫規則。
當外部請求來到Apache,Apache調用重寫規則中的定義來重寫由用戶瀏覽器指定請求的
URI,最后被重寫的URI如果是重定向,則送由瀏覽器作再一次請求;如果是代理則把重寫
后的URI交給代理模塊請求最終的內容(Content),最后把內容送回給瀏覽器。
六: 何時使用.htaccess中的重寫規則定義?
如果你對你的的網站內容所在的服務器沒有管理員權限,或你的網站放在ISP的服務器
上托管等等條件下,你無法改寫主設置文件,然而你能對你的WEB站點內容所在的目錄
有寫權限,則你能設置自己的.htaccess
文件達到同樣的目的。但你需要確定主設置文件中對你的網站所在的目錄定義了下面的內
容:
Options Indexes FollowSymLinks
AllowOverride all
否則你的.htaccess不會工作。
七: 應用舉例
假定Apache被編譯安裝在主機192.168.1.56的/usr/local/apache/ 目錄下面,我們編
譯進了重寫和代理模塊。
1) 隱藏Apache下的某個目錄,使得對該目錄的所有請求都重定向到另一個文件。
a> httpd.conf的實現方法
我們放下面的部分到/usr/local/apache/conf/httpd.conf
options Indexes followsymlinks
allowoverride all
rewriteengine on
rewritebase /
rewriterule ^(.*)$ index.html.en [R=301]
注:rewriteengine on 為重寫引擎開關,如果設為off,則所有重寫規則定義將不被應
用,該開關的另一好處就是如果為了臨時拿掉重寫規則,則改為off再重啟動Apache即
可,不必將下面一條條的重寫規則注釋掉。
rewritebase / 的作用是如果在下面的rewriterule定義中被重寫后的部分(此處為文件
名index.html.en)前面沒有/,則是相對目錄,相對於這個rewritebase后面的定義也就
是/usr/local/apache/htdocs/index.html.en,否則,如果此處沒有rewritebase /這
一項,則被重寫成
http://192.168.1.56/usr/local/apache/htdocs/manual/index.html.en ,顯然是
不正確的。
不過這里我們也能不用rewritebase / , 而改為
rewriteengine on
rewriterule ^(.*)$ /index.html.en [R=301]
或
rewriteengine on
rewriterule ^(.*)$ http://192.168.1.56/index.html.en [R=301]
b> .htaccess的實現方法
我們先放下面的部分到httpd.conf
options Indexes followsymlinks
allowoverride all
然后放下面的部分到/usr/local/apache/htdocs/manual/.htaccess中
rewriteengine on
rewritebase /
rewriterule ^(.*)$ index.html.en [R=301]
注:對文件.htaccess所作的所有改動不必重啟動Apache.
問:要是把這個manual目錄重定向到用戶jephe的自己的主目錄呢?
用下面的.htaccess方案。
rewriteengine on
rewritebase /~jephe/
rewriterule ^(.*)$ $1 [R=301]
則對manual目錄下所有文件的請求被重定向到~jephe目錄下相同文件的請求。
2) 轉換www.username.domain.com的對於username的主頁請求為
www.domain.com/username
對於HTTP/1.1的請求包括一個Host: HTTP頭,我們能用下面的規則集重寫
http://www.username.domain.com/anypath 到 /home/username/anypath
Rewriteengine on
rewritecond %{HTTP_HOST} ^www\.[^.]+\.host\.com$
rewriterule ^(.+) %{HTTP_HOST}$1 [C]
rewriterule ^www\.([^.]+)\.host\.com(.*) /home/$1$2
注:
rewritecond 條件重寫規則,當滿足后面定義的條件后才會應用下面的重寫規則,
rewritecond有各種變量
,請查閱相關文件。
3) 防火牆上的重寫規則代理內部網段上服務器的請求。
NameVirtualhost 1.2.3.4
servername www.domain.com
rewriteengine on
proxyrequest on
rewriterule ^/(.*)$ http://192.168.1.3/$1 [P,L]
注:當外部瀏覽器請求www.domain.com時被解析到IP地址1.2.3.4 ,Apache 交出
mod_rewrite處理轉換成
http://192.168.1.3/$1后再交由代理模塊mod_proxy得到內容后傳送回用戶的瀏覽器。
4) 基本預先設定的轉換MAP表進行重寫 rewritemap
轉換www.domain.com/{countrycode}/anypath 到Map表中規定的URI,上面是虛擬主機
中的定義
rewritelog /usr/local/apache/logs/rewrite.log
rewriteloglevel 9
rewriteengine on
proxyrequest on
rewritemap sitemap txt:/usr/local/apache/conf/rewrite.map
rewriterule ^/([^/]+)+/(.*)$ http://%{REMOTE_HOST}::$1 [C]
rewriterule (.*)::([a-z]+)$ ${sitemap:$2|http://h.i.j.k