write:
作用:
將chunk中的數據寫到輸出緩沖區
利用write方法寫json數據
- 我們自己手動序列化json的那種方式Content-Type 的屬性值為text-html
- 而我們采用write自動序列化方式,我們的content-type 屬性為application/json
set_default_headers():
作用:
- 在進入HTTP響應方法之前被調用
- 可以重新寫該方法來設置默認的headers
注意:
- 在這個HTTP處理方法中使用set_header設置的字段會覆蓋set_default_headers()的值
- 這個set_header和set_default_headers()是有執行的先后順序的,默認那個當然那先就執行了
set_status(status_code,reason=none):
作用:為響應設置狀態碼
參數:
status_code:
- 狀態碼的值,為int類型
- 如果reason的值為none,則狀態碼必須為正常值
reason
- String類型
- 描述狀態碼的詞組,比如
404 not found
中的not found
重定向 self.redirect(url)
:
作用:
- 比如你有時候寫index,有時候不寫,都能進到首頁里面,這就是重定向的作用
- 重定向到url網址
示例:
class RedirectHandler(RequestHandler):def get(self):# 直接就重定向了self.redirect("/")
self.send_error(status_code = 500,**kwargs)
:
- 作用:
- 拋出HTTP錯誤狀態碼,默認為500
- tornado會調用write_error()方法進行處理
- 對應Django里面自定義404一樣
write_error(status_code,**kwargs)
:
- 作用:
- 用來處理send_error拋出的錯誤信息,并返回給瀏覽器錯誤界面
- 示例:
class ErrorHandler(RequestHandler):def write_error(self, status_code: int, **kwargs: Any) -> None:if status_code == 500:self.write("服務器內部錯誤500了")elif status_code == 404:self.write("資源不存在")else:self.write("我也不知道是啥錯誤")def get(self):# 直接就重定向了flag = self.get_query_argument("flag")if flag == '0':print("有錯誤")self.send_error(500)# 這里拋出錯誤,下面就不會執行了print("沒毛病")self.write("you are right!")
路由的反向解析
這個tornado里面的比Django的反向解析還要簡單一點
給路由起個名字,便于url改變后,跳轉鏈接失效
應用端
class Application(tornado.web.Application):def __init__(self):handlers = [(r"/", index.IndexHandler),(r"/sunck", index.SunckHandler,{'name':"victor",'age':19}),# 狀態碼(r"/status", index.StatusHandler),# 重定向(r"/index", index.RedirectHandler),# 錯誤處理# iserror?flag=2# 如果等于0就說明,有錯誤,不等于0就說明沒有錯誤(r"/iserror", index.ErrorHandler),tornado.web.url(r"/kaige",index.KaigeHandler,name='kaige'),]super(Application,self).__init__(handlers)
視圖函數
class IndexHandler(RequestHandler):def get(self):self.write("main page info tornado!")self.write("<br>")url = self.reverse_url("kaige")self.write("<a href='%s'>去另一個頁面</a>" % (url))# self.write("<a href="+url+">去另一個頁面</a>")
tornado.Web.RequestHandler
利用HTTP協議向服務器傳遞參數
提取uri的特定部分
http://127.0.0.1:8080/good/nice/handsome/cool
實例代碼,app部分
''' (r"/good/(\w+)/(\w+)/(\w+)", index.GoodHandler),'''
(r"/good/(?P<p1>\w+)/(?P<p3>\w+)/(?P<p2>\w+)", index.GoodHandler),
視圖函數部分
class GoodHandler(RequestHandler):def get(self,p1,p3,p2):self.write("GoodHandler kaige !")self.write("<br>")self.write(p3)self.write("<br>")self.write(p2)self.write("<br>")self.write(p1)
查詢字符串(GET方式傳遞參數)
http://127.0.0.1:8080/zhangmanyu?a=1&b=2&c=4
類型
這里有一個方法
def get_query_argument(self,name: str,default: Union[None, str, _ArgDefaultMarker] = _ARG_DEFAULT,strip: bool = True,) -> Optional[str]:
參數
name:
- 從get請求參數中返回指定參數的值
- 如果出現同名參數,理論上這個方法會返回最后一個值
default
- 如果我們設置了為未傳遞name參數,它會返回默認的值
strip
- 表示是否過濾掉兩邊的空白字符
- 默認為True,過濾
http://127.0.0.1:8080/zhangmanyu?a=1&a=2&c=4
類型
- 一般情況下,很少出現這種情況的
def get_query_arguments(self, name: str, strip: bool = True) -> List[str]:
- 參數: 同上
請求體攜帶數據(POST方式傳遞參數)
- 這個厲害了,比Django方便,不用在定義一路由函數了,直接在類里面加一個方法就就行了
- 原型在這里
def get_body_argument(self,name: str,default: Union[None, str, _ArgDefaultMarker] = _ARG_DEFAULT,strip: bool = True,) -> Optional[str]:
既可以獲取GET請求,也可以獲取POST請求
- 直接就上原型就OK了,你不僅要學會舉一反三,還要自己進行拓展
- 原型在這里
def get_argument( # noqa: F811self,name: str,default: Union[None, str, _ArgDefaultMarker] = _ARG_DEFAULT,strip: bool = True,
) -> Optional[str]:
- 其實有時候,有的結構,看源碼才能理解的更加的深刻
- 還有一個多個的,也是這么回事兒
def get_arguments(self, name: str, strip: bool = True) -> List[str]:
在HTTP報文頭中,增加自定義的字段
request對象
作用
- 存儲了關于請求的相關信息
比如:
HTTPServerRequest(protocol='http', host='127.0.0.1:8080', method='GET', uri='/zhuyin', version='HTTP/1.1', remote_ip='127.0.0.1')
屬性
- method: HTTP請求的方式
- host: 被請求的主機名(服務器的主機名)
- uri: 請求的完整資源地址,包括路徑和get查詢的參數部分
- path: 請求的路徑部分
- query: 請求參數部分
- version: 使用的HTTP版本
- headers: 請求的協議頭,字典類型
- body: 請求體數據(POST)
- remote_ip: 客戶端的ip地址
- files: 用戶上傳的文件,字典類型
tornado.httputil.HTTPFile對象
- 功能:在我們上傳文件中才能看到他
- 作用:
是收到的文件對象
屬性:
- filename: 文件的實際名字
- body: 文件的數據實體
- content-type: 上傳文件的類型
文件上傳
首先,先要濾清一個數據結構,就是request.file對象的數據結構
'''
一個request.file對象的結構示例
{'file': [{'filename': 'a.txt','body': b'suck is a wonderful man','content_type': 'text/plain'},{'filename': 'reg.md','body': b'x9xa0','content_type': 'application/octet-stream'}]'img': [{'filename': 'a.img','body': b'as\dfhg\ahhf\a\\h\ahfh\af','content_type': 'text/plain'}]
}
'''
然后,用循環來進行遍歷!
class UpFileHandler(RequestHandler):def get(self):self.render("upfile.html")def post(self):self.write("上傳成功!")contents = self.request.filesfor content in contents:fileArr = contents[content]for fileObj in fileArr:file_path = os.path.join(BASE_DIR,"upfile/"+fileObj.filename)with open(file_path,"wb") as f:f.write(fileObj.body)print("文件寫入成功")
我知道,要是看不懂那就加一點批注唄!
''' 導入系統操作模塊,用于存儲接受的文件'''
import os
# 導入BASE_DIR,定位到服務器中的絕對路徑
from config import BASE_DIR
from tornado.web import RequestHandlerclass IndexHandler(RequestHandler):def get(self):self.write("main page info tornado!")class UpFileHandler(RequestHandler):'''用于上傳文件的視圖類,其中包含顯示表單的get方法和用于處理上傳的POST方法'''# get方法,加載表單模板def get(self):self.render("upfile.html")# 文件上傳指定是POST請求啦def post(self):# 用于接收上傳的信息self.write("上傳成功!")# 通過request.files對象來獲取所有文件對象內容contents = self.request.files# 遍歷最大的字典,拿到沒個name類型的字典的鍵# 其中content是字典中的鍵,比如file,imgfor content in contents:# 通過鍵獲取值,拿到相同name的文件列表# 這個filearr,就是一個listfileArr = contents[content]# 遍歷文件列表# 這個fileObj又是一個dict字典類型for fileObj in fileArr:# 定義存儲路徑# 通過BASE_DIR來獲取服務器的絕對位置# 其中通過這個fileObj的字典的filename鍵,# 來獲取文件名字,來定義存儲路徑的文件名稱file_path = os.path.join(BASE_DIR,"upfile/"+fileObj.filename)# 寫入文件with open(file_path,"wb") as f:# 文件的內容就是bodyf.write(fileObj.body)# TODO 這里還需要處理的就是,用戶上傳同名文件# 導致文件重新在服務器中覆蓋的問題print("文件寫入成功")
相似文章
tornado學習筆記day01
tornado學習筆記day02
tornado學習筆記day03
tornado學習筆記day04
tornado學習筆記day05
tornado學習筆記day06
tornado學習筆記day07
tornado學習筆記day08