使用bottle進行web開發(5):Generating Content
在純粹的 WSGI中,你的應用能返回的數據類型是十分有限的,你必須返回可叠代的字符串,你能返回字符串是因為字符串是可以叠代的,但是這導致服務器將你的內容按一字符一字符的傳送,這個時候,Unicode 字符將不允許被返回了,這是肯定不行的。
Bottle 則支持了更多的數據類型,它甚至添加了一個 Content-Length
頭信息,並且自動編碼 Unicode 數據,下面列舉了 Bottle 應用中,你可以返回的數據類型,並且簡單的介紹了一下這些數據類型的數據都是怎麽被 Bottle 處理的:
數據類型 | 介紹 |
---|---|
字典(Dictionaries) | Python 內置的字典類型數據將自動被轉換為 JSON 字符串,並且添加 Content-Type |
空字符串,False,None或者任何非真的數據 | Bottle 將為這類數據創建 ContentLength 頭文件,被設置為 0 返回至瀏覽器 |
Unicode 字符串 | Unicode 字符串將自動的按 Content-Type 頭文件中定義的編碼格式進行編碼(默認為UTF8),接著按普通的字符串進行處理 |
字節串(Byte strings) | Bottle 返回整個字符串(而不是按字節一個一個返回),同時增加 Content-Length 頭文件標示字節串長度 |
HTTPError HTTPResponse 實例 |
返回這些實例就像拋出異常一樣,對於 HTTPError,錯誤將被與相關函數處理 |
文件對象 | 然後具有 .read() 方法的對象都被看作文件或者類似文件的對象進行處理,並傳送給 WSGI 服務器框架定義wsgi.file_wrapper 回調函數,某一些WSGI服務器會使用系統優化的請求方式(Sendfile)來發送文件。 |
叠代器與生成品 | 你可以在你的回調函數使用 yield 或者 返回一個叠代器,只要yield的對象是字符串,Unicode 字符串,HTTPError 或者 HTTPResponse 對象就行,但是不允許使用嵌套的叠代器,需要註意的是,當 yield 的值第一次為非空是, HTTP 的狀態 和 頭文件將被發送到 瀏覽器 |
如果你返回一個 str
類子類的實例,並且帶有 read()
方法,那它還是將按 字符串進行處理,因為字符串有更高一級的優先處理權。
改變默認編碼
Bottle 依照 Content-Type 頭文件中 charset
參數來對字符串進行編碼,該頭文件默認為 text/html; charset=UTF8
,並且可以被Response.content_type
屬性修改,或者直接被 Response.charset
屬性修改:
from bottle import response
@route(‘/iso‘)
def get_iso():
response.charset = ‘ISO-8859-15‘
return u‘This will be sent with ISO-8859-15 encoding.‘
@route(‘/latin9‘)
def get_latin():
response.content_type = ‘text/html; charset=latin9‘
return u‘ISO-8859-15 is also known as latin9.‘
由於某些罕見的原因,Python 編碼的名稱可能與 HTTP 編碼的名稱不一致,這時你需要做兩方法的工作首先設置Response.content_type
頭文件,然後還需要設置 Response.charset
。
靜態文件
你可以直接返回文件,但是 Bottle 推薦使用 static_file()
方法,它會自動的猜測文件的 mime-type,追加 Last-Modified
頭文件,完全的自定義需要服務的文件路徑,並且能處理錯誤(比如 404),並且它還支持 If-Modified-Since
頭文件並且可以返回 304 Not Modified
響應,你還可以使用一個自定義的 mime-type 來重寫 mime-type 猜測的值。
from bottle import static_file
@route(‘/images/:filename#.*\.png#‘)
def send_image(filename):
return static_file(filename, root=‘/path/to/image/files‘, mimetype = ‘image/png‘)
@route(‘/static/:filename‘)
def send_static(filename):
return static_file(filename, root=‘/path/to/static/files‘)
如果你真的需要,你還可以以異常的形式拋出文件。
強制下載
絕大多數瀏覽器在知道下載的文件的MIME類型並且該文件類型被綁定到某一個應用程序時(比如PDF文件),它們都會自動的打開該文件,如果你不想這樣,你可以強制的要求瀏覽器進行下載。
@route(‘/download/:filename‘)
def download(filename):
return static_file(filename, root=‘/path/to/static/files‘, download=filename)
使用bottle進行web開發(5):Generating Content