《高性能網站建設指南》規則11—避免重定向

規則11——避免重定向

重定向用於將用戶從一個URL從新路由到另外一個URL。重定向有不少種——301和302是最經常使用的兩種。重定向可能有不少不一樣的緣由,包括網站從新設計、跟蹤流量、記錄廣告點擊和創建易於記憶的URL。javascript

重定向的類型

當web服務器向瀏覽器返回一個重定向時,響應中就會擁有一個範圍在3xx的狀態碼。這表示用戶代理必須執行進一步操做才能完成請求。
300 Multiple Choices(基於Content-Type)
301 Moved Permancently
302 Moved Temporarily(亦稱Found)
303 See Other(對302的說明)
304 Not Modified
305 Use Proxy
306 (已廢棄)
307 Temporary Redirect (對302的說明)html

"304 Not Modified"並不真的是重定向——它用來響應條件GET請求,避免下載已經存在於流量器緩存中的數據java

301和302是使用得最多的。狀態碼303和307是在http1.1規範中添加的,用來澄清對302的使用(濫用),可是幾乎沒有人用303和307,絕大多數網站仍然在沿用302.web

下面是一個301響應頭的一個示例
avatar
瀏覽器會自動將用戶帶到Location字段所給出的URL。重定向所必需的全部信息都出如今這個頭中了。響應體一般是空的。無論叫什麼名字,301和302響應在實際中都不會被緩存,除非有附加的頭——如Expires或Cache-Control等——要求它這麼作。apache

還有其餘方法能夠自動將用戶重定向到其餘URL。HTML文檔的頭中包含的meta refresh標籤能夠在其content屬性所指定的秒數以後重定向用戶編程

<meta http-equiv="refresh" content="0; url=http://strbesouders.com/newuri">

javascript也能夠用於執行重定向,將document.location設置爲指望的url便可。若是你必須進行重定向,最好的技術是使用標準的3xx HTTP狀態碼,這主要是爲了確保後退按鈕可以正確工做。後端

重定向以外的其餘選擇

缺乏結尾的斜線

不少web開發人員沒有意識到,在url的結尾必須出現斜線(/)而沒出現時,如http://astrology.yahoo.com/as... 包含了一個到http://astrology.yahoo.com/as... 的重定向。當缺乏結尾的斜線時發送重定向有着很充分的理由——它容許自動索引(autoindexing,自動轉到默認的index.html上)而且可以得到與當前目錄相關的url(如logo.gif)。然而,不少流行的web頁面並不依賴自動索引,而是依賴特定的url和處理器。另外,url一般也與根目錄相關而不是和當前目錄相關。瀏覽器

注意當主機名後缺乏結尾斜線時不會發生重定向。例如,http://www.yahoo.com 不會產生重定向。然而,你在瀏覽器中看到的最終的url是包含結尾斜線的——http://www.yahoo.com/ .致使自動產生結尾斜線的緣由是,瀏覽器在運行get請求時必需指定一些路徑。若是沒有路徑,例如http://www.yahoo.com 它就會簡單地使用文檔根(/)
GET / HTTP 1.1
當缺乏結尾斜線時發送重定向是不少web服務器的默認行爲,包括Apache. Alias指令是一種簡單的方法。另外一種選擇是使用mod_rewrite模塊,但Alias更加簡單。(注1)Astrology網站的問題能夠經過向Apache配置中添加下列內容來解決——
Alias /astrology /user/local/apache/htdocs/astrology/astrology.html緩存

若是使用Apache2.0中的處理器,一種更爲清晰的解決方案是使用DirectorySlash指令。假設有一個名爲astrologyhandler的處理器,能夠像下面這樣使用DirectorySlash安全

<Localtion /astrology>
    DirectorySlash Off
    SetHandler astrologyhandler
</Localtion>

這些方法都不能解決查找與當期目錄相關的url問題,所以頁面中組件的url必須與根目錄相關。並且,你還必須知道各模塊運行的順序(尤爲是mod_dir和mod_autoindex),由於這樣使用DirectorySlash可能會有安全隱患。

總之,若是你的網站包含目錄並使用了自動索引,用戶就必須忍受一個到達預期頁面的重定向。檢查一下你的web日誌就能看到發出了多少301狀態,這能幫助你認識到多麼值得去解決缺乏結尾斜線的問題。

鏈接網站

想象一下網站後端被重寫的情形。這常常發生,新的實現中的url極可能會有所不一樣。將用戶從舊的url轉移到新的url的最簡單的方式就是重定向。重定向是使用定義良好的API——url來整合兩個代碼基礎的一種方式。

將舊網站鏈接到新網站只是重定向這種常見應用中的表現形式之一。其餘形式還包括將一個網站的不一樣部分鏈接起來,以及基於一些條件(瀏覽器類型、用戶帳戶類型等)來引導用戶。使用重定向來鏈接兩個網站很簡單並且只須要不多的額外代碼。

其實整合後端還有其餘的選擇,但比重定向須要更多的開發工做,不過這樣不會損害用戶體驗。

1.Alias、mod_rewrite和DirectorySlash要求除url以外還要提交到一個接口(處理器或文件名),但易於實現。
2.若是兩個後端位於同一臺服務器,則它們的代碼極可能本身就能鏈接。例如,舊的處理器代碼能夠經過編程調用新的處理器代碼。
3.若是域名變了,可使用一個CNAME(一條DNS記錄,用於建立從一個域名指向另外一個域名的別名)讓兩個主機名指向相同的服務器。若是能作到這一點,這裏提到的技術(Alias、mod_rewrite、DirectorySlash和直接鏈接代碼)就是可行的。

跟蹤內部流量

重定向常常用於跟蹤用戶流量的流向。例如,sports連接的url是http://www.yahoo.com/r/26.單...,其Location被設置爲http://sports.yahoo.com/。經過分析來自www.yahoo.com的web服務器日誌能夠得知人們離開Yahoo!的首頁後的流量去向。

另外一種選擇是使用Referer日誌來跟蹤流量去向。每一個http請求都包含一個url,代表從哪一個頁面發起的請求,也就是引用方(有的時候沒有引用頁,當用戶鍵入url或使用書籤時)。在這裏,當用戶從Yahoo!主頁導航到Sports頁時,sports.yahoo.com的訪問日誌中會包含一個Referer,其值爲http://www/yahoo.com/

跟蹤出站流量

出站流量使用referer就不太現實了
Yahoo!search目前將每一個搜索結果連接包裝到一個重定向中來解決跟蹤的問題。搜索結果的url都指向rds.yahoo.com並將最終的目標看成參數包含在該url中。例如,下面是指向wikipedia的「Performance」詞條的搜索結果連接
http://rds.yahoo.com/[...]5742/**http%3a/en.wikipedia.org/wiki/Performance
單擊這個搜索結果會訪問rds.yahoo.com,它將返回一個302響應,其Location被設置爲http://en.wikipedia.org/wiki/...**參數就能跟蹤用戶去了哪裏。這個重定向使得獲取目標頁面變慢了。

除了重定向,還能夠選擇信標——一個http請求,其url中包含有跟蹤信息。跟蹤信息能夠從信標web服務器的訪問日誌中提取出來。信標響應一般是一個1px*1px的透明圖片;不過204響應更爲優秀,由於它更小,歷來不會被緩存,並且絕對不會改變瀏覽器狀態。
在Yahoo!search,目標是不管什麼時候用戶單擊搜索結果連接時都要發送一個信標。這經過爲每一個鏈接提供onClick處理器來完成(當啓用了javascript時)。onclick處理器將調用一個函數,請求一個圖片,並在圖片的url中包含要跟蹤的信息。
avatar
這種狀況下,挑戰是發送信標和頁面自身被卸載之間的競態情形。圖片信標的onload處理器能夠用於確保在卸載文檔以前信標應傳送完畢。
avatar
這種方法可能和使用重定向同樣慢,另外一種方式是使用XMLHttpRequest來發送信標,但在卸載頁面以前只需等請求到達readyState 2便可。這比等待重定向的整個http響應要快,但你必須決定是否有必要採起這麼複雜的方式。

美化URL

使用重定向的另外一種動機是使url更加美觀而且易於記憶。如http://www.google.com/tools/f... -> http://www.google.com.
可是,使用alias、mod_rewrite、DirectorySlash和直接連接代碼來避免重定向也能達到目的。

相關文章
相關標籤/搜索