# if the host doesn't start with www. then add it and redirect
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# if it cant find the image, try find the image on another domain
RewriteCond %{REQUEST_URI} \.(jpg|jpeg|gif|png)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*)$ http://www.example.com/ [L]
要了解 mod_rewrite 是什麼,您首先需要了解 Web 伺服器的工作原理。 Web 伺服器回應 HTTP 請求。最基本層級的 HTTP 請求如下所示:
GET /foo/bar.html HTTP/1.1
這是瀏覽器向 Web 伺服器請求 URL/foo/bar.html 的簡單請求。需要強調的是,它並沒有請求檔案,它只是請求一些任意的 URL。該請求也可能如下所示:
GET /foo/bar?baz=42 HTTP/1.1
這與 URL 請求一樣有效,而且顯然與文件無關。
Web 伺服器是一個偵聽連接埠的應用程序,接受來自該連接埠的 HTTP 請求並回傳回應。 Web 伺服器完全可以自由地以任何它認為合適的方式回應任何請求/以您配置它回應的任何方式回應。此回應不是一個文件,而是一個 HTTP 回應,它可能與任何磁碟上的物理文件有任何關係,也可能沒有任何關係。 Web 伺服器不一定是 Apache,還有許多其他 Web 伺服器,它們都只是持久運行並附加到回應 HTTP 請求的連接埠的程式。你可以自己寫一個。本段的目的是讓您擺脫 URL 直接等於文件的任何觀念,理解這一點非常重要。 :)
大多數 Web 伺服器的預設配置是在硬碟上尋找與 URL 相符的檔案。如果伺服器的文檔根設定為/var/www,它可能會尋找檔案/var/www/foo/bar. html 存在,如果存在則提供它。如果檔案以“.php”結尾,它將呼叫 PHP 解釋器並傳回結果。所有這些關聯都是完全可配置的;文件不必以“.php”結尾,Web 伺服器即可透過 PHP 解釋器運行該文件,並且 URL 不必與磁碟上的任何特定文件匹配才能發生某些事情。
mod_rewrite 是一種重寫內部請求處理的方法。當 Web 伺服器收到對 URL /foo/bar 的請求時,您可以將該 URL 重寫為其他內容,然後 Web 伺服器會在磁碟上尋找它符合的檔案。簡單的例子:
為了擴展deceze的答案,我想提供一些範例和一些其他 mod_rewrite 功能的解釋。 p>
以下所有範例均假設您已在
.htaccess
檔案中包含RewriteEngine On
。重寫範例
讓我們舉個例子:
此規則分為 4 個部分:
RewriteRule
- 啟動重寫規則^blog/([0-9] )/([A-Za-z0-9-\ ] )/?$
- 這稱為模式,但是我'只需將其稱為規則的左邊- 您想要重寫的內容blog/index.php?id=$1&title=$2
- 稱為替換,或重寫規則的右邊 - 您想要重寫的內容[NC,L,QSA]
是重寫規則的標誌,以逗號分隔,稍後我將詳細解釋上面的重寫將允許您連結到類似
/blog/1/foo/
的內容,並且它實際上會載入/blog/index.php?id=1&title=foo 代码>.
規則的左側
^
表示頁面名稱的開頭- 因此它將重寫example.com/blog/...
但不會重寫example.com/foo/部落格/...
(…)
括號代表一個正規表示式,我們可以將其捕獲為規則右側的變數。在這個例子中:([0-9] )
- 符合長度至少為 1 個字元且僅包含數字值(即 0-9)的字串。這可以透過規則右邊的$1
來引用-
或code> (注意
用反斜線轉義,因為如果不轉義它,這將作為正規表示式重複字元)。這可以透過規則右邊的
$2
來引用?
表示前面的字元是可選的,因此在本例中/blog/1/foo/
和/blog/1/foo
code> 將重寫到相同位置$
表示這是我們要符合的字串的結尾標誌
這些選項會新增在重寫規則末端的方括號中,用於指定某些條件。同樣,您可以在文件中閱讀許多不同的標誌,但我將介紹一些更常見的標誌:
無大小寫標誌意味著重寫規則不區分大小寫,因此對於上面的範例規則,這意味著
/blog/1/foo/
和/BLOG/1/ foo /
(或其任何變體)將被匹配。最後一個標誌表示這是應該處理的最後一條規則。這意味著當且僅當該規則匹配時,在當前重寫處理運行中不會評估進一步的規則。如果規則不匹配,則將照常嘗試所有其他規則。如果您不設定
L
標誌,則隨後的所有規則都會套用至重寫的 URL。自 Apache 2.4 起,您也可以使用
[END]
標誌。與之匹配的規則將完全終止進一步的別名/重寫處理。 (而[L]
標誌通常會觸發第二輪,例如在重寫子目錄或重寫子目錄時。)查詢字串追加標誌允許我們將額外的變數傳遞到指定的 URL,這些變數將會加入到原始的 get 參數中。對於我們的範例,這意味著像
/blog/1/foo/?comments=15
這樣的內容將載入/blog/index.php?id=1&title=foo&comments=15
這個標誌不是我在上面的範例中使用的標誌,但我認為值得一提。這允許您指定 http 重定向,並可以選擇包含狀態代碼(例如
R=301
)。例如,如果您想在 /myblog/ 上執行 301 重定向到 /blog/,您只需編寫以下規則:重寫條件
重寫條件使重寫更加強大,讓您可以指定針對更具體情況的重寫。您可以在文件中阅读很多条件>,但我將介紹一些常見範例並對其進行解釋:
這是一種非常常見的做法,它將在您的網域前面加上
www.
(如果尚不存在)並執行 301 重定向。例如,載入http://example.com/blog/
會將您重新導向到http://www.example.com/blog/
這種情況稍微不太常見,但這是一個很好的範例,說明如果文件名稱是伺服器上存在的目錄或文件,則不會執行該規則。
%{REQUEST_URI} \.(jpg|jpeg|gif|png)$ [NC]
只會對檔案副檔名為jpg、jpeg、gif 或png 的檔案執行重寫(大小寫為不敏感)。%{REQUEST_FILENAME} !-f
將檢查目前伺服器上是否存在該文件,如果不存在則執行重寫%{REQUEST_FILENAME} !-d
將檢查目前伺服器上是否存在該文件,如果不存在則執行重寫要了解 mod_rewrite 是什麼,您首先需要了解 Web 伺服器的工作原理。 Web 伺服器回應 HTTP 請求。最基本層級的 HTTP 請求如下所示:
這是瀏覽器向 Web 伺服器請求 URL
/foo/bar.html
的簡單請求。需要強調的是,它並沒有請求檔案,它只是請求一些任意的 URL。該請求也可能如下所示:這與 URL 請求一樣有效,而且顯然與文件無關。
Web 伺服器是一個偵聽連接埠的應用程序,接受來自該連接埠的 HTTP 請求並回傳回應。 Web 伺服器完全可以自由地以任何它認為合適的方式回應任何請求/以您配置它回應的任何方式回應。此回應不是一個文件,而是一個 HTTP 回應,它可能與任何磁碟上的物理文件有任何關係,也可能沒有任何關係。 Web 伺服器不一定是 Apache,還有許多其他 Web 伺服器,它們都只是持久運行並附加到回應 HTTP 請求的連接埠的程式。你可以自己寫一個。本段的目的是讓您擺脫 URL 直接等於文件的任何觀念,理解這一點非常重要。 :)
大多數 Web 伺服器的預設配置是在硬碟上尋找與 URL 相符的檔案。如果伺服器的文檔根設定為
/var/www
,它可能會尋找檔案/var/www/foo/bar. html
存在,如果存在則提供它。如果檔案以“.php”結尾,它將呼叫 PHP 解釋器並傳回結果。所有這些關聯都是完全可配置的;文件不必以“.php”結尾,Web 伺服器即可透過 PHP 解釋器運行該文件,並且 URL 不必與磁碟上的任何特定文件匹配才能發生某些事情。mod_rewrite 是一種重寫內部請求處理的方法。當 Web 伺服器收到對 URL
/foo/bar
的請求時,您可以將該 URL 重寫為其他內容,然後 Web 伺服器會在磁碟上尋找它符合的檔案。簡單的例子:此規則表示只要請求符合“/foo/bar”,請將其重寫為“/foo/baz”。 然後該請求將被處理,就像
/foo/baz。這可用於各種效果,例如:
此規則符合任何內容(
.*
) 並捕獲它((..)
),然後重寫它以附加“.html” 」。換句話說,如果/foo/bar
是請求的URL,則將按照/foo/bar.html
已被請求的方式進行處理。有關正則表達式匹配、捕獲和替換的詳細信息,請參閱http://regular-expressions.info。另一個常遇到的規則是:
這再次匹配任何內容並將其重寫到文件index.php,並在
url
查詢參數中附加最初請求的 URL。即,對於傳入的任何和所有請求,都會執行檔案index.php,並且該檔案將有權存取$_GET['url']
中的原始請求,因此它可以做任何它想做的事情有了它。首先,您將這些重寫規則放入您的網頁伺服器設定檔。 Apache 還允許*您將它們放入文檔根目錄中名為
.htaccess
的檔案中(即 .php 檔案旁邊)。* 如果主 Apache 設定檔允許;它是可選的,但通常會啟用。
mod_rewrite 不做什麼
mod_rewrite 不會神奇地讓所有 URL 變得「漂亮」。這是一個常見的誤解。如果您的網站中有此連結:
mod_rewrite 無法讓之變得漂亮。為了使其成為一個漂亮的鏈接,您必須:
將連結改為漂亮的連結:
使用上述任何一種方法,在伺服器上使用 mod_rewrite 來處理 URL
/my/pretty/link
的請求。(可以使用
mod_substitute
結合轉換傳出的HTML 頁面及其包含的連結。儘管這通常比僅僅更新HTML 資源更費力。)mod_rewrite 可以做很多事情,您可以建立非常複雜的匹配規則,包括連結多個重寫、將請求代理到完全不同的服務或機器、返回特定的 HTTP 狀態代碼作為回應、重定向請求等。它非常強大,可以如果您了解基本的 HTTP 請求回應機制,將會非常有用。它不會自動使您的連結變得漂亮。
請參閱官方文件以了解所有可能的標誌和選項。