Tornado源碼分析 --- Redirect重定向

「重定向」簡單介紹:

  「重定向」指的是HTTP重定向,是HTTP協議的一種機制。當client向server發送一個請求,要求獲取一個資源時,在server接收到這個請求後發現請求的這個資源實際存放在另外一個位置,因而server在返回的response中寫入那個請求資源的正確的URL,並設置reponse的狀態碼爲301(永久)或者 302(暫時),當client接受到這個response後就會根據新的URL從新發起請求。重定向有一個典型的特症,即,當一個請求被重定向之後,最終瀏覽器上顯示的URL每每再也不是開始時請求的那個URL了。這就是重定向的由來。web

 

下面咱們先看Redirect的源碼,以後分析完源碼後能夠更好的理解其用法。正則表達式

Tornado Redirect源碼分析:

  在 web.py 中發現有倆個地方實現了重定向的機制:瀏覽器

  1. 基類 RequestHandler 中定義的 self.redirect:

 1 def redirect(self, url, permanent=False, status=None):  2     if self._headers_written:  3         raise Exception("Cannot redirect after headers have been written")  4     if status is None:  5         status = 301 if permanent else 302
 6     else:  7         assert isinstance(status, int) and 300 <= status <= 399
 8  self.set_status(status)  9     self.set_header("Location", utf8(url)) 10     self.finish()

  先看傳入進來的參數:網絡

  • url:重定向後所返回的新的URL地址
  • permanent:默認爲False,表示該重定向爲臨時性的;若是爲True,則該重定向爲永久性。
  • status:當status被指定了值的話,那個該值將會做爲HTTP返回給客戶端的狀態碼;若是沒有指定特定的值,那麼根據上方的permanent狀態,若是permanent爲True,則該status返回301;若是permanent爲False,則該status返回302。

  注: 默認值爲302。app

  分析:函數

  1. 經過檢測 self._headers_written 的值,來判斷是否該請求已經被返回給了客戶端:                                                                                                                                                                                                                                                在 基類 RequestHandler 的初始化中,self._headers_written False,以後若是當前輸出的緩衝區已經flush到了網絡的時候,函數 def flush() 中會將 self._headers_written True。因此此時頭信息headers已經別寫入了請求且已經返回給了客戶端,是沒法進行重定向了。
  2. status狀態碼默認爲302,除非permanent參數爲True(永久重定向)纔會返回301。若是status指定了特定的值的話,那麼對指定的值進行數據類型判斷,而且status的範圍爲 300~399,不然會返回異常。
  3. 寫入狀態信息,以及 字段「Location」 (用來重定向接收方到非請求URL的位置來完成請求或標識新的資源)的值
  4. 調用 finish() ,完成該HTTP請求。

  2. 類 RedirectHandler實現的重定向: 

1 class RedirectHandler(RequestHandler):
2     def initialize(self, url, permanent=True):
3          self._url = url
4          self._permanent = permanent
5  
6     def get(self, *args):
7          self.redirect(self._url.format(*args), permanent=self._permanent)

  介紹和用法:源碼分析

  • 重定向客戶端的GET請求到給定的URL。
  • 須要提供關鍵參數URL傳入該處理類中,例如:
1 application = web.Application([ 2     (r"/oldpath", web.RedirectHandler, {"url": "/newpath"}), 3 ])

   在Application中調用該 RedirectHandlerf方法,給定參數「url」,其會將 地址’/oldpath‘ 重定向到 ’/newpath‘ 中。url

  • 該類也支持對重定向URL地址進行正則表達式匹配,例如爲了實現交換第一個和第二個參數部分,同事保留其他部分不變: 
1 application = web.Application([ 2     (r"/(.*?)/(.*?)/(.*)", web.RedirectHandler, {"url": "/{1}/{0}/{2}"}), 3 ])

   最終的URL可使用格式化方法: str.format,子串會被捕獲而後進行對應的匹配。在上面的例子中,一個 「a/b/c」 的請求可以被格式化,以下:   spa

str.format("/{1}/{0}/{2}", "a", "b", "c")  # -> "/b/a/c"

  源碼分析:code

  1. 經過 initiaialize() 函數進行參數 URL, permanent 的初始化。permanent初始化爲True,則該重定向爲永久化的。
  2. 定義 get() 函數,調用 基類中定義的 self.redirect 進行重定向的處理。

 

兩種重定向方法的比較和思考:

  對於兩種方法中的 permanent 參數,類 RedirectHandler 中默認爲True(永久性重定向301);self.redirect中默認爲False(臨時性重定向302);

  緣由:self.redirect 多數狀況下被用於用戶自定義的狀況下進行重定向操做(例如環境變動、用戶認證、以及表單提交),因此其默認爲臨時的重定向。類RedirectHandler 是每次匹配到該請求URL的時候就觸發重定向。

相關文章
相關標籤/搜索