1.Cookie
# 向cookie中存儲數(shù)據(jù)
self.set_cookie("info", "msg")
#取cookie中的數(shù)據(jù)
info_ = self.get_cookie("info")
#但上面簡單的cookies直接顯示數(shù)據(jù)甩卓,容易被他人利用珠增,使用加密的cookie
# 向cookie中存儲數(shù)據(jù)
self.set_secure_cookie("info", "msg")
info_ = self.get_secure_cookie("info")
#添加混淆碼论泛,加密cookie
app = Application(
[......],
#混淆碼一般用 base64.b64encode 格式的隨機碼
cookie_secret='yYsdHBeySj2XPhzewQYsycmLHRwXsko9lz4c3sEGLMnJix0cF7JKPZc+HN7BBizJ'
)
#清除cookie
clear_cookie()
cookie有時間設(shè)置茴恰,通過self.cookie(name, value, expires_days)來給添加一個cookie數(shù)據(jù),如果不設(shè)置過期時間expries_days,該cookie就是一個會話級別的臨時cookie着帽,一旦會話超時或者瀏覽器完全關(guān)閉的情況下揣钦,cookie中存儲的數(shù)據(jù)就會丟失;如果設(shè)置了過期時間expires_days該cookie就是一個永久cookie涨岁,永久的cookie默認為30天時限拐袜。
永久時間設(shè)置:為None時,關(guān)閉會話立即失效梢薪, 小于等于0時cookie沒作用蹬铺,創(chuàng)建后立即過期。
- 附加
#轉(zhuǎn)碼encode
#解碼decode
#禁止跨域請求秉撇,APP添加設(shè)置
xsrf_cookies=True,
#前端網(wǎng)頁請求時添加令牌
{% module xsrf_form_html() %}
2.登錄認證
#導入登錄認證模塊
from tornado.web import authenticated
#在函數(shù)處理中添加 get_current_user()函數(shù)丛塌,判斷current_user當前用戶是否登錄的認證。
#重寫get_current_user()函數(shù)~指定在什么情況下用戶是登錄狀態(tài)畜疾!
def get_current_user(self):
name = self.get_secure_cookie("login")
if name is not None:
return True
return False
# authenticated裝飾器~用于判斷用戶是否具有登錄狀態(tài)
@authenticated
def get(self):
# 獲取cookie中的數(shù)據(jù)
name = self.get_secure_cookie("login")
self.render("index.html", name=name)
if __name__ == "__main__":
app = Application(
[......],
#設(shè)置錯誤信息顯示是否詳細
debug=True,
#這是登錄認證判斷沒有登錄(cookie ‘login’ 沒有用戶)時跳轉(zhuǎn)的路由
#當完成登錄時會自動返回當時請求的頁面赴邻。有記憶功能。
login_url='/login',
)
3.異步
- 前端異步
通過前端Ajax實現(xiàn)異步處理啡捶,和其他服務(wù)器項目進行數(shù)據(jù)通信
如:天氣預(yù)報 http://wthrcdn.etouch.cn/weather_mini?city=
通過前端頁面提交城市到天氣預(yù)報服務(wù)器查詢姥敛,返回數(shù)據(jù)到前端頁面,自己服務(wù)器不參與瞎暑。
注意:有時數(shù)據(jù)返回的是字符串彤敛,要轉(zhuǎn)化為json格式供自己使用// 獲取天氣數(shù)據(jù),轉(zhuǎn)換數(shù)據(jù)~string->json var _weather = JSON.parse(data).data; // DOM操作渲染數(shù)據(jù) var $today1 = $("<p>").text("日期:" + _weather.forecast[0].date);
- 后端同步
前端請求時了赌,通過自己的服務(wù)器向他人的服務(wù)器獲取數(shù)據(jù)墨榄,再返還給前端。# 引入需要的模塊 from tornado.httpclient import HTTPClient # 定義一個天氣預(yù)報處理類 class WeatherHandler(RequestHandler): # 同步方式~從其他服務(wù)器獲取數(shù)據(jù) def get(self): #前端接收的數(shù)據(jù) city = self.get_argument("city") # 創(chuàng)建一個客戶端對象 client = HTTPClient() # 抓取指定的url地址中的數(shù)據(jù)勿她,得到一個響應(yīng)對象response #抓取到的數(shù)據(jù)是存放在body屬性中 response = client.fetch("http://wthrcdn.etouch.cn/weather_mini?city=" + city) self.write(response.body)
- 后端異步
過程類似同步袄秩,只是方法不一樣。#異步操作對象 模塊 from tornado.httpclient import AsyncHTTPClient #定義異步操作天氣預(yù)報的視圖處理類 class WeatherHandler(RequestHandler): #通過注解裝飾器,告訴tornado這個get處理方法是異步的~不需要自動返回數(shù)據(jù) @asynchronous def get(self): #獲取參數(shù)數(shù)據(jù) city = self.get_argument("city") # 創(chuàng)建一個異步操作對象 client = AsyncHTTPClient() # 異步對象抓取數(shù)據(jù) client.fetch("http://wthrcdn.etouch.cn/weather_mini?city=" + city, callback=self.deal_response) #這個函數(shù)就是異步對象的回調(diào)函數(shù)之剧,當異步數(shù)據(jù)獲取完成時調(diào)用執(zhí)行的函數(shù) def deal_response(self, response): content = response.body # 將數(shù)據(jù)返回給前端頁面 self.write(content) # 通過finish()函數(shù)告訴tornado異步操作結(jié)束郭卫,手工控制返回數(shù)據(jù) self.finish()
附加:
后端同步與異步的區(qū)別:通過siege壓力測試工具壓力測試,可以看出同步與異步的差距背稼。
當并發(fā)量與訪問時間相同時贰军,異步的處理效率遠高于同步的方式。
4.長連接
一般實現(xiàn)聊天室蟹肘,網(wǎng)頁客服等
- 前端頁面
<script> // 創(chuàng)建一個js中的 websocket 對象词疼,保持和服務(wù)器之間的通信 // var _websocket = new WebSocket("websocket連接字符串,使用websocket協(xié)議連接") var _websocket = new WebSocket("ws://192.168.11.102:8000/chat"); // 隨時等待接收服務(wù)器的消息:保持一個長連接帘腹,一旦服務(wù)器有消息的話贰盗,需要實時接收。 _websocket.onmessage = function(e) { // 接受服務(wù)器發(fā)送的數(shù)據(jù) e 一般默認為 e var _content = e.data; }; $("#send").click(function() { // 當點擊按鈕的時候竹椒,需要給服務(wù)器發(fā)送數(shù)據(jù) var $msg = $("#msg").val(); _websocket.send($msg) }) // 處理讓消息窗口的滾動條顯示在最底下的位置 $("#history").scrollTop($("#history")[0].scrollHeight) </script>
- 后端服務(wù)器
#導入后端服務(wù)器長連接模塊 from tornado.websocket import WebSocketHandler # 定義聊天消息長連接處理類 #和客戶端保持長連接的視圖處理類需要重寫父類的方法完成和客戶端的通信 class ChatHandler(WebSocketHandler): # 定義一個保存所有用戶的集合 set() online_users = set() # 1.重寫open()函數(shù)童太,保存接入的用戶數(shù)據(jù) def open(self): #新的客戶端連接的時候,open()函數(shù)自動執(zhí)行胸完, # 將接入的數(shù)據(jù)保存到集合中 add(self) self.online_users.add(self) # 向所有人發(fā)送消息书释,用戶誰連接上了 for user in self.online_users: # 發(fā)送數(shù)據(jù) write_message() 獲取用戶IP self.request.remote_ip user.write_message("[%s上線了]" % self.request.remote_ip) # 2.重寫on_message()函數(shù),獲取客戶端發(fā)送的消息并轉(zhuǎn)發(fā)給所有用戶 def on_message(self, message): # 函數(shù)on_message會自動接收客戶端發(fā)送的數(shù)據(jù)赊窥,數(shù)據(jù)包含在message變量中 # 向所有人發(fā)送消息爆惧,用戶誰說了什么 # 重寫on_close()函數(shù),當斷開某個連接時锨能,移除在服務(wù)器記錄的數(shù)據(jù) def on_close(self): # 當一個客戶端連接斷開時自動執(zhí)行的函數(shù)on_close() #移除用戶數(shù)據(jù) remove(self) self.online_users.remove(self) # 向所有人發(fā)送消息扯再,用戶誰離開了 # 允許跨域訪問,不然無法訪問 def check_origin(self, origin): return True