国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Python學習筆記_進階篇(一)_淺析tornado web框架

這篇具有很好參考價值的文章主要介紹了Python學習筆記_進階篇(一)_淺析tornado web框架。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

tornado簡介

1、tornado概述

Tornado就是我們在 FriendFeed 的 Web 服務器及其常用工具的開源版本。Tornado 和現(xiàn)在的主流 Web 服務器框架(包括大多數(shù) Python 的框架)有著明顯的區(qū)別:它是非阻塞式服務器,而且速度相當快。得利于其 非阻塞的方式和對epoll的運用,Tornado 每秒可以處理數(shù)以千計的連接,因此 Tornado 是實時 Web 服務的一個 理想框架。我們開發(fā)這個 Web 服務器的主要目的就是為了處理 FriendFeed 的實時功能 ——在 FriendFeed 的應用里每一個活動用戶都會保持著一個服務器連接。(關(guān)于如何擴容 服務器,以處理數(shù)以千計的客戶端的連接的問題,請參閱The C10K problem)

Tornado代表嵌入實時應用中最新一代的開發(fā)和執(zhí)行環(huán)境。 Tornado 包含三個完整的部分:

(1)、Tornado系列工具, 一套位于主機或目標機上強大的交互式開發(fā)工具和使用程序;

(2)、VxWorks 系統(tǒng), 目標板上高性能可擴展的實時操作系統(tǒng);

(3)、可選用的連接主機和目標機的通訊軟件包 如以太網(wǎng)、串行線、在線仿真器或ROM仿真器。

2、tornado特點

Tornado的獨特之處在于其所有開發(fā)工具能夠使用在應用開發(fā)的任意階段以及任何檔次的硬件資源上。而且,完整集的Tornado工具可以使開發(fā)人員完全不用考慮與目標連接的策略或目標存儲區(qū)大小。Tornado 結(jié)構(gòu)的專門設計為開發(fā)人員和第三方工具廠商提供了一個開放環(huán)境。已有部分應用程序接口可以利用并附帶參考書目,內(nèi)容從開發(fā)環(huán)境接口到連接實現(xiàn)。Tornado包括強大的開發(fā)和調(diào)試工具,尤其適用于面對大量問題的嵌入式開發(fā)人員。這些工具包括C和C++源碼級別的調(diào)試器,目標和工具管理,系統(tǒng)目標跟蹤,內(nèi)存使用分析和自動配置. 另外,所有工具能很方便地同時運行,很容易增加和交互式開發(fā)。

3、tornado模塊索引

最重要的一個模塊是web, 它就是包含了 Tornado 的大部分主要功能的 Web 框架。其它的模塊都是工具性質(zhì)的, 以便讓 web 模塊更加有用 后面的 Tornado 攻略 詳細講解了 web 模塊的使用方法。

主要模塊

  • web - FriendFeed 使用的基礎 Web 框架,包含了 Tornado 的大多數(shù)重要的功能
  • escape - XHTML, JSON, URL 的編碼/解碼方法
  • database - 對 MySQLdb 的簡單封裝,使其更容易使用
  • template - 基于 Python 的 web 模板系統(tǒng)
  • httpclient - 非阻塞式 HTTP 客戶端,它被設計用來和 webhttpserver 協(xié)同工作
  • auth - 第三方認證的實現(xiàn)(包括 Google OpenID/OAuth、Facebook Platform、Yahoo BBAuth、FriendFeed OpenID/OAuth、Twitter OAuth)
  • locale - 針對本地化和翻譯的支持
  • options - 命令行和配置文件解析工具,針對服務器環(huán)境做了優(yōu)化

底層模塊

  • httpserver - 服務于 web 模塊的一個非常簡單的 HTTP 服務器的實現(xiàn)
  • iostream - 對非阻塞式的 socket 的簡單封裝,以方便常用讀寫操作
  • ioloop - 核心的 I/O 循環(huán)

tornado框架使用

1、安裝tornado

pip install tornado
源碼安裝:https://pypi.python.org/packages/source/t/tornado/tornado-4.3.tar.gz

2、先寫一個入門級的代碼吧,相信大家都能看懂,聲明:tornado內(nèi)部已經(jīng)幫我們實現(xiàn)socket。

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import tornado.web
import tornado.ioloop

class IndexHandler(tornado.web.RequestHandler):

    def get(self, *args, **kwargs):
        self.write("Hello World, My name is 張巖林")

application = tornado.web.Application([
    (r'/index',IndexHandler),
])

if __name__ == "__main__":
    application.listen(8080)
    tornado.ioloop.IOLoop.instance().start()

第一步:執(zhí)行腳本,監(jiān)聽 8080 端口

第二步:瀏覽器客戶端訪問 /index --> http://127.0.0.1:8080/index

第三步:服務器接受請求,并交由對應的類處理該請求

第四步:類接受到請求之后,根據(jù)請求方式(post / get / delete …)的不同調(diào)用并執(zhí)行相應的方法

第五步:然后將類的方法返回給瀏覽器

tornado路由系統(tǒng)

在tornado web框架中,路由表中的任意一項是一個元組,每個元組包含pattern(模式)和handler(處理器)。當httpserver接收到一個http請求,server從接收到的請求中解析出url path(http協(xié)議start line中),然后順序遍歷路由表,如果發(fā)現(xiàn)url path可以匹配某個pattern,則將此http request交給web應用中對應的handler去處理。

由于有了url路由機制,web應用開發(fā)者不必和復雜的http server層代碼打交道,只需要寫好web應用層的邏輯(handler)即可。Tornado中每個url對應的是一個類。

#!/usr/bin/env python
# -*- coding:utf-8 -*-
__auth__ = "zhangyanlin"

import tornado.web
import tornado.ioloop

class IndexHandler(tornado.web.RequestHandler):

    def get(self, *args, **kwargs):
        self.write("Hello World, My name is 張巖林")

class LoginHandler(tornado.web.RequestHandler):

    def get(self, *args, **kwargs):
        self.write("<input type = 'text'>")

class RegisterHandler(tornado.web.RequestHandler):

    def get(self, *args, **kwargs):
        self.write("<input type = 'password'>")

application = tornado.web.Application([
    (r'/index/(?P<page>\d*)',IndexHandler),  # 基礎正則路由
    (r'/login',LoginHandler),
    (r'/register',RegisterHandler),
])

# 二級路由映射
application.add_handlers('buy.zhangyanlin.com$',[
    (r'/login', LoginHandler),
])

if __name__ == "__main__":
    application.listen(8080)
    tornado.ioloop.IOLoop.instance().start()

觀察所有的網(wǎng)頁的內(nèi)容,下面都有分頁,當點擊下一頁后面的數(shù)字也就跟著變了,這種就可以用基礎正則路由來做,下面我來給大家下一個網(wǎng)頁分頁的案例吧

Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記

#!/usr/bin/env python
# -*- coding:utf-8 -*-
__auth__ = "zhangyanlin"

import tornado.web
import tornado.ioloop

LIST_INFO = [
    {'username':'zhangyanlin','email':'133@164.com'}
]
for i in range(200):
    temp = {'username':str(i)+"zhang",'email':str(i)+"@163.com"}
    LIST_INFO.append(temp)


class Pagenation:

    def __init__(self,current_page,all_item,base_url):  #當前頁 內(nèi)容總數(shù) 目錄
        try:
            page = int(current_page)
        except:
            page = 1
        if page < 1:
            page = 1

        all_page,c = divmod(all_item,5)
        if c > 0:
            all_page +=1

        self.current_page = page
        self.all_page = all_page
        self.base_url = base_url

    @property
    def start(self):
        return (self.current_page - 1) * 5

    @property
    def end(self):
        return self.current_page * 5

    def string_pager(self):
        list_page = []
        if self.all_page < 11:
            s = 1
            t = self.all_page + 1
        else:
            if self.current_page < 6:
                s = 1
                t = 12
            else:
                if (self.current_page + 5) < self.all_page:
                    s = self.current_page-5
                    t = self.current_page + 6
                else:
                    s = self.all_page - 11
                    t = self.all_page +1

        first = '<a href = "/index/1">首頁</a>'
        list_page.append(first)
        # 當前頁
        if self.current_page == 1:
            prev = '<a href = "javascript:void(0):">上一頁</a>'
        else:
            prev = '<a href = "/index/%s">上一頁</a>'%(self.current_page-1,)
        list_page.append(prev)

        #頁碼
        for p in range(s,t):
            if p== self.current_page:
                temp = '<a class = "active" href = "/index/%s">%s</a>'%(p,p)
            else:
                temp = '<a href = "/index/%s">%s</a>' % (p, p)
            list_page.append(temp)



        # 尾頁
        if self.current_page == self.all_page:
            nex = '<a href = "javascript:void(0):">下一頁</a>'
        else:
            nex = '<a href = "/index/%s">下一頁</a>' % (self.current_page + 1,)
        list_page.append(nex)

        last = '<a href = "/index/%s">尾頁</a>'%(self.all_page)
        list_page.append(last)


        #跳轉(zhuǎn)
        jump = '''<input type="text"><a onclick = "Jump('%s',this);">GO</a>'''%('/index/')
        script = '''
            <script>
                function Jump(baseUrl,ths){
                    var val = ths.previousElementSibling.value;
                    if (val.trim().length > 0){
                        location.href = baseUrl + val;
                    }
                }
            </script>
        '''
        list_page.append(jump)
        list_page.append(script)
        str_page = "".join(list_page)

        return str_page

class IndexHandler(tornado.web.RequestHandler):

    def get(self, page):
        obj = Pagenation(page,len(LIST_INFO),'/index/')
        current_list = LIST_INFO[obj.start:obj.end]
        str_page = obj.string_pager()
        self.render('index.html', list_info=current_list, current_page=obj.current_page, str_page=str_page)

application = tornado.web.Application([
    (r'/index/(?P<page>\d*)',IndexHandler)

])


if __name__ == "__main__":
    application.listen(8080)
    tornado.ioloop.IOLoop.instance().start()

tornado服務端demo

Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .pager a{
            display: inline-block;
            padding: 5px 6px;
            margin: 10px 3px;
            border: 1px solid #2b669a;
            text-decoration:none;

        }
        .pager a.active{
            background-color: #2b669a;
            color: white;
        }
    </style>
</head>
<body>
    <h3>顯示數(shù)據(jù)</h3>
    <table border="1">
        <thead>
            <tr>
                <th>用戶名</th>
                <th>郵箱</th>
            </tr>
        </thead>
        <tbody>
            {% for line in list_info %}
                <tr>
                    <td>{{line['username']}}</td>
                    <td>{{line['email']}}</td>
                </tr>
            {% end %}
        </tbody>
    </table>
    <div class="pager">
        {% raw str_page %}
    </div>
</body>
</html>

前端HTML文件

注:兩個文件必須放在同一個文件夾下,中間前端代碼中有用到XSS攻擊和模板語言,這兩個知識點下面會詳細解釋

tornado 模板引擎

Tornao中的模板語言和django中類似,模板引擎將模板文件載入內(nèi)存,然后將數(shù)據(jù)嵌入其中,最終獲取到一個完整的字符串,再將字符串返回給請求者。

Tornado 的模板支持“控制語句”和“表達語句”,控制語句是使用 {%%} 包起來的 例如 {% if len(items) > 2 %}。表達語句是使用 {{}} 包起來的,例如 {{ items[0] }}。

控制語句和對應的 Python 語句的格式基本完全相同。我們支持 iffor、whiletry,這些語句邏輯結(jié)束的位置需要用 {% end %} 做標記。還通過 extendsblock 語句實現(xiàn)了模板繼承。這些在 template 模塊 的代碼文檔中有著詳細的描述。

注:在使用模板前需要在setting中設置模板路徑:“template_path” : “views”

settings = {
    'template_path':'views',             #設置模板路徑,設置完可以把HTML文件放置views文件夾中
    'static_path':'static',              # 設置靜態(tài)模板路徑,設置完可以把css,JS,Jquery等靜態(tài)文件放置static文件夾中
    'static_url_prefix': '/sss/',        #導入時候需要加上/sss/,例如<script src="/sss/jquery-1.9.1.min.js"></script>
    'cookie_secret': "asdasd",           #cookie生成秘鑰時候需提前生成隨機字符串,需要在這里進行渲染
    'xsrf_cokkies':True,                 #允許CSRF使用
}


application = tornado.web.Application([  
    (r'/index',IndexHandler),  
],**settings)                           #需要在這里加載

文件目錄結(jié)構(gòu)如下:

Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記

1、模板語言基本使用for循環(huán),if…else使用,自定義UIMethod以UIModule

Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記

 #!/usr/bin/env python
# -*- coding:utf-8 -*-
import tornado.ioloop
import tornado.web
import uimodule as md
import uimethod as mt

INPUT_LIST = []
class MainHandler(tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
        name = self.get_argument('xxx',None)
        if name:
            INPUT_LIST.append(name)
        self.render("index.html",npm = "NPM88888",xxoo = INPUT_LIST)

    def post(self, *args, **kwargs):
        name = self.get_argument('xxx')
        INPUT_LIST.append(name)
        self.render("index.html", npm = "NPM88888", xxoo = INPUT_LIST)
        # self.write("Hello, World!!!")

settings = {
    'template_path':'tpl',  # 模板路徑的配置
    'static_path':'statics',  # 靜態(tài)文件路徑的配置
    'ui_methods':mt,        # 自定義模板語言
    'ui_modules':md,        # 自定義模板語言
}

#路由映射,路由系統(tǒng)
application = tornado.web.Application([
    (r"/index",MainHandler),
],**settings)


if __name__ == "__main__":
    # 運行socket
    application.listen(8000)
    tornado.ioloop.IOLoop.instance().start()

start.py

Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記

from tornado.web import UIModule
from tornado import escape

class custom(UIModule):

    def render(self, *args, **kwargs):
        return "張巖林"

uimodule

Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記

def func(self,arg):
    return arg.lower()

uimethod

Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link type="text/css" rel="stylesheet" href="static/commons.css">
</head>
<body>
    <script src="static/zhang.js"></script>
    <h1>Hello world</h1>
    <h1>My name is zhangyanlin</h1>
    <h1>輸入內(nèi)容</h1>
    <form action="/index" method="post">
        <input type="text" name="xxx">
        <input type="submit" value="提交">
    </form>
    <h1>展示內(nèi)容</h1>
    <h3>{{ npm }}</h3>
    <h3>{{ func(npm)}}</h3>
    <h3>{% module custom() %}</h3>
    <ul>
        {% for item in xxoo %}
            {% if item == "zhangyanlin" %}
                <li style="color: red">{{item}}</li>
            {% else %}
                <li>{{item}}</li>
            {% end %}
        {% end %}
    </ul>
</body>
</html>

index.html

2、母板繼承

(1)、相當于python的字符串格式化一樣,先定義一個占位符

Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <title>帥哥</title>
    <link href="{{static_url("css/common.css")}}" rel="stylesheet" />
    {% block CSS %}{% end %}
</head>
<body>

    <div class="pg-header">

    </div>
    
    {% block RenderBody %}{% end %}
   
    <script src="{{static_url("js/jquery-1.8.2.min.js")}}"></script>
    
    {% block JavaScript %}{% end %}
</body>
</html>

layout.html

(2)、再子板中相應的位置繼承模板的格式

Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記

{% extends 'layout.html'%}
{% block CSS %}
    <link href="{{static_url("css/index.css")}}" rel="stylesheet" />
{% end %}

{% block RenderBody %}
    <h1>Index</h1>

    <ul>
    {%  for item in li %}
        <li>{{item}}</li>
    {% end %}
    </ul>

{% end %}

{% block JavaScript %}
    
{% end %}

index.html

3、導入內(nèi)容

Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記

<div>
    <ul>
        <li>張巖林帥</li>
        <li>張巖林很帥</li>
        <li>張巖林很很帥</li>
    </ul>
</div>

content.html

Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <title>張巖林</title>
    <link href="{{static_url("css/common.css")}}" rel="stylesheet" />
</head>
<body>

    <div class="pg-header">
        {% include 'header.html' %}
    </div>
    
    <script src="{{static_url("js/jquery-1.8.2.min.js")}}"></script>
    
</body>
</html>

index.html

在模板中默認提供了一些函數(shù)、字段、類以供模板使用:

escape: tornado.escape.xhtml_escape 的別名
xhtml_escape: tornado.escape.xhtml_escape 的別名
url_escape: tornado.escape.url_escape 的別名
json_encode: tornado.escape.json_encode 的別名
squeeze: tornado.escape.squeeze 的別名
linkify: tornado.escape.linkify 的別名
datetime: Python 的 datetime 模組
handler: 當前的 RequestHandler 對象
request: handler.request 的別名
current_user: handler.current_user 的別名
locale: handler.locale 的別名
_: handler.locale.translate 的別名
static_url: for handler.static_url 的別名
xsrf_form_html: handler.xsrf_form_html 的別名

當你制作一個實際應用時,你會需要用到 Tornado 模板的所有功能,尤其是 模板繼承功能。所有這些功能都可以在template 模塊 的代碼文檔中了解到。(其中一些功能是在 web 模塊中實現(xiàn)的,例如 UIModules

tornado cookie

Cookie,有時也用其復數(shù)形式Cookies,指某些網(wǎng)站為了辨別用戶身份、進行session跟蹤而儲存在用戶本地終端上的數(shù)據(jù)(通常經(jīng)過加密)。定義于RFC2109和2965都已廢棄,最新取代的規(guī)范是RFC6265。(可以叫做瀏覽器緩存)

1、cookie的基本操作

 #!/usr/bin/env python
# -*- coding:utf-8 -*-
   
import tornado.ioloop
import tornado.web
   
   
class MainHandler(tornado.web.RequestHandler):
    def get(self):
        print(self.cookies)              # 獲取所有的cookie
        self.set_cookie('k1','v1')       # 設置cookie
        print(self.get_cookie('k1'))     # 獲取指定的cookie
        self.write("Hello, world")
   
application = tornado.web.Application([
    (r"/index", MainHandler),
])
   
   
if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

2、加密cookie(簽名)

Cookie 很容易被惡意的客戶端偽造。加入你想在 cookie 中保存當前登陸用戶的 id 之類的信息,你需要對 cookie 作簽名以防止偽造。Tornado 通過 set_secure_cookie 和 get_secure_cookie 方法直接支持了這種功能。 要使用這些方法,你需要在創(chuàng)建應用時提供一個密鑰,名字為 cookie_secret。 你可以把它作為一個關(guān)鍵詞參數(shù)傳入應用的設置中:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
   
import tornado.ioloop
import tornado.web
    
class MainHandler(tornado.web.RequestHandler):
    def get(self):
         if not self.get_secure_cookie("mycookie"):             # 獲取帶簽名的cookie
             self.set_secure_cookie("mycookie", "myvalue")      # 設置帶簽名的cookie
             self.write("Your cookie was not set yet!")
         else:
             self.write("Your cookie was set!")
application = tornado.web.Application([
    (r"/index", MainHandler),
])
   
if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

簽名Cookie的本質(zhì)是:

寫cookie過程:

    將值進行base64加密
    對除值以外的內(nèi)容進行簽名,哈希算法(無法逆向解析)
    拼接 簽名 + 加密值

讀cookie過程:

    讀取 簽名 + 加密值
    對簽名進行驗證
    base64解密,獲取值內(nèi)容

用cookie做簡單的自定義用戶驗證,下面會寫一個絕對牛逼的自定義session用戶驗證

Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記

#!/usr/bin/env python
# -*- coding:utf-8 -*-
 
import tornado.ioloop
import tornado.web
 
class BaseHandler(tornado.web.RequestHandler):
 
    def get_current_user(self):
        return self.get_secure_cookie("login_user")
 
class MainHandler(BaseHandler):
 
    @tornado.web.authenticated
    def get(self):
        login_user = self.current_user
        self.write(login_user)
 
class LoginHandler(tornado.web.RequestHandler):
    def get(self):
        self.current_user()
 
        self.render('login.html', **{'status': ''})
 
    def post(self, *args, **kwargs):
 
        username = self.get_argument('name')
        password = self.get_argument('pwd')
        if username == '張巖林' and password == '123':
            self.set_secure_cookie('login_user', '張巖林')
            self.redirect('/')
        else:
            self.render('login.html', **{'status': '用戶名或密碼錯誤'})
 
settings = {
    'template_path': 'template',
    'static_path': 'static',
    'static_url_prefix': '/static/',
    'cookie_secret': 'zhangyanlinhaoshuai',
}
 
application = tornado.web.Application([
    (r"/index", MainHandler),
    (r"/login", LoginHandler),
], **settings)
 
 
if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

自定義驗證登錄

3、JavaScript操作Cookie

由于Cookie保存在瀏覽器端,所以在瀏覽器端也可以使用JavaScript來操作Cookie。

/*
設置cookie,指定秒數(shù)過期,
name表示傳入的key,
value表示傳入相對應的value值,
expires表示當前日期在加5秒過期
 */

function setCookie(name,value,expires){
    var temp = [];
    var current_date = new Date();
    current_date.setSeconds(current_date.getSeconds() + 5);
    document.cookie = name + "= "+ value +";expires=" + current_date.toUTCString();
}

注:jQuery中也有指定的插件 jQuery Cookie 專門用于操作cookie,猛擊這里

4、自定義session

本來這想新開一個帖子,但是還是把代碼貼在這吧,有用到session驗證的時候直接復制拿走就好

Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import tornado.web
import tornado.ioloop

container = {}
class Session:
    def __init__(self, handler):
        self.handler = handler
        self.random_str = None

    def __genarate_random_str(self):
        import hashlib
        import time
        obj = hashlib.md5()
        obj.update(bytes(str(time.time()), encoding='utf-8'))
        random_str = obj.hexdigest()
        return random_str

    def __setitem__(self, key, value):
        # 在container中加入隨機字符串
        # 定義專屬于自己的數(shù)據(jù)
        # 在客戶端中寫入隨機字符串
        # 判斷,請求的用戶是否已有隨機字符串
        if not self.random_str:
            random_str = self.handler.get_cookie('__session__')
            if not random_str:
                random_str = self.__genarate_random_str()
                container[random_str] = {}
            else:
                # 客戶端有隨機字符串
                if random_str in container.keys():
                    pass
                else:
                    random_str = self.__genarate_random_str()
                    container[random_str] = {}
            self.random_str = random_str # self.random_str = asdfasdfasdfasdf

        container[self.random_str][key] = value
        self.handler.set_cookie("__session__", self.random_str)

    def __getitem__(self, key):
        # 獲取客戶端的隨機字符串
        # 從container中獲取專屬于我的數(shù)據(jù)
        #  專屬信息【key】
        random_str =  self.handler.get_cookie("__session__")
        if not random_str:
            return None
        # 客戶端有隨機字符串
        user_info_dict = container.get(random_str,None)
        if not user_info_dict:
            return None
        value = user_info_dict.get(key, None)
        return value


class BaseHandler(tornado.web.RequestHandler):
    def initialize(self):
        self.session = Session(self)

自定義session

XSS攻擊和CSRF請求偽造

XSS

跨站腳本攻擊(Cross Site Scripting),為不和層疊樣式表(Cascading Style Sheets, CSS)的縮寫混淆,故將跨站腳本攻擊縮寫為XSS。惡意攻擊者往Web頁面里插入惡意Script代碼,當用戶瀏覽該頁之時,嵌入其中Web里面的Script代碼會被執(zhí)行,從而達到惡意攻擊用戶的特殊目的。

tornado中已經(jīng)為我們給屏蔽了XSS,但是當我們后端向前端寫前端代碼的時候傳入瀏覽器是字符串,而不是形成代碼格式。所以就需要一個反解,在傳入模板語言中前面加一個raw,例如{{ raw zhangyanlin }},這樣通俗的講可能不太懂,寫一段代碼,可能就懂了

Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記

class IndexHandler(tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
        jump = '''<input type="text"><a onclick = "Jump('%s',this);">GO</a>'''%('/index/')
        script = '''
            <script>
                function Jump(baseUrl,ths){
                    var val = ths.previousElementSibling.value;
                    if (val.trim().length > 0){
                        location.href = baseUrl + val;
                    }
                }
            </script>
        '''
        self.render('index.html',jump=jump,script=script)  #傳入兩個前端代碼的字符串

start.py

Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .pager a{
            display: inline-block;
            padding: 5px;
            margin: 3px;
            background-color: #00a2ca;
        }
        .pager a.active{
            background-color: #0f0f0f;
            color: white;
        }
    </style>
</head>
<body>
    <div class="pager">
        {% raw jump %}
        {% raw script%}
    </div>
</body>
</html>    

index.html

CSRF

CSRF(Cross-site request forgery跨站請求偽造,也被稱為“one click attack”或者session riding,通常縮寫為CSRF或者XSRF,是一種對網(wǎng)站的惡意利用。盡管聽起來像跨站腳本(XSS),但它與XSS非常不同,并且攻擊方式幾乎相左。XSS利用站點內(nèi)的信任用戶,而CSRF則通過偽裝來自受信任用戶的請求來利用受信任的網(wǎng)站。與XSS攻擊相比,CSRF攻擊往往不大流行(因此對其進行防范的資源也相當稀少)和難以防范,所以被認為比XSS更具危險性。
當前防范 XSRF 的一種通用的方法,是對每一個用戶都記錄一個無法預知的 cookie 數(shù)據(jù),然后要求所有提交的請求中都必須帶有這個 cookie 數(shù)據(jù)。如果此數(shù)據(jù)不匹配 ,那么這個請求就可能是被偽造的。

Tornado 有內(nèi)建的 XSRF 的防范機制,要使用此機制,你需要在應用配置中加上 xsrf_cookies 設定:xsrf_cookies=True,再來寫一段代碼,來表示一下:

Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import tornado.web
import tornado.ioloop

class CsrfHandler(tornado.web.RequestHandler):

    def get(self, *args, **kwargs):
        self.render('csrf.html')

    def post(self, *args, **kwargs):
        self.write('張巖林已經(jīng)收到客戶端發(fā)的請求偽造')


settings = {
    'template_path':'views',
    'static_path':'statics',
    'xsrf_cokkies':True,        # 重點在這里,往這里看
}

application = tornado.web.Application([
    (r'/csrf',CsrfHandler)
],**settings)

if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

start.py

Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/csrf" method="post">
        {% raw xsrf_form_html() %}
        <p><input name="user" type="text" placeholder="用戶"/></p>
        <p><input name='pwd' type="text" placeholder="密碼"/></p>
        <input type="submit" value="Submit" />
        <input type="button" value="Ajax CSRF" onclick="SubmitCsrf();" />
    </form>
    
    <script src="/statics/jquery-1.12.4.js"></script>
    <script type="text/javascript">

        function ChangeCode() {
            var code = document.getElementById('imgCode');
            code.src += '?';
        }
        function getCookie(name) {
            var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");
            return r ? r[1] : undefined;
        }

        function SubmitCsrf() {
            var nid = getCookie('_xsrf');
            $.post({
                url: '/csrf',
                data: {'k1': 'v1',"_xsrf": nid},
                success: function (callback) {
                    // Ajax請求發(fā)送成功有,自動執(zhí)行
                    // callback,服務器write的數(shù)據(jù) callback=“csrf.post”
                    console.log(callback);
                }
            });
        }
    </script>
</body>
</html>

csrf.html

簡單來說就是在form驗證里面生成了一段類似于自己的身份證號一樣,攜帶著他來訪問網(wǎng)頁

tornado上傳文件

上傳文件這塊可以分為兩大類,第一類是通過form表單驗證進行上傳,還有一類就是通過ajax上傳,下面就來介紹一下這兩類

1、form表單上傳文件

Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記

 #!/usr/bin/env python
# -*- coding:utf-8 -*-

import tornado.web
import tornado.ioloop
import os

class IndexHandler(tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
        self.render('index.html')

    def post(self, *args, **kwargs):
        file_metas = self.request.files["filename"]     # 獲取文件信息
        for meta in file_metas:                         
            file_name = meta['filename']                # 獲得他的文件名字
            file_names = os.path.join('static','img',file_name)
            with open(file_names,'wb') as up:           # 打開本地一個文件
                up.write(meta['body'])                  # body就是文件內(nèi)容,把他寫到本地

settings = {
    'template_path':'views',
    'static_path':'static',
    'static_url_prefix': '/statics/',
}

application = tornado.web.Application([
    (r'/index',IndexHandler)
],**settings)

if __name__ == '__main__':
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

start.py

Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>上傳文件</title>
</head>
<body>
    <form action="/index" method="post" enctype="multipart/form-data">
        <input type="file" name = "filename">
        <input type="submit" value="提交">
    </form>
</body>
</html>

index.html

2、ajax上傳文件

Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記

<!DOCTYPE html>
<html>
<head lang= "en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <form id="my_form" name="form" action="/index" method="POST"  enctype="multipart/form-data" >
        <div id="main">
            <input name="filename" id="my_file"  type="file" />
            <input type="button" name="action" value="Upload" onclick="redirect()"/>
            <iframe id='my_iframe' name='my_iframe' src=""  class="hide"></iframe>
        </div>
    </form>

    <script>
        function redirect(){
            document.getElementById('my_iframe').onload = Testt;
            document.getElementById('my_form').target = 'my_iframe';
            document.getElementById('my_form').submit();

        }
        
        function Testt(ths){
            var t = $("#my_iframe").contents().find("body").text();
            console.log(t);
        }
    </script>
</body>
</html>

HTML iframe

Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <input type="file" id="img" />
    <input type="button" onclick="UploadFile();" value="提交"/>

    <script src="/statics/jquery-1.12.4.js"></script>
    <script>
        function UploadFile(){
            var fileObj = $("#img")[0].files[0];
            var form = new FormData();
            form.append("filename", fileObj);

            $.ajax({
                type:'POST',
                url: '/index',
                data: form,
                processData: false,  // tell jQuery not to process the data
                contentType: false,  // tell jQuery not to set contentType
                success: function(arg){
                    console.log(arg);
                }
            })
        }
    </script>
</body>
</html>

Jquery 上傳

Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <input type="file" id="img" />
    <input type="button" onclick="UploadFile();" value="提交" />
    <script>
        function UploadFile(){
            var fileObj = document.getElementById("img").files[0];

            var form = new FormData();
            form.append("filename", fileObj);

            var xhr = new XMLHttpRequest();
            xhr.open("post", '/index', true);
            xhr.send(form);
        }
    </script>
</body>
</html>

XML提交

Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import tornado.web
import tornado.ioloop
import os

class IndexHandler(tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
        self.render('index.html')

    def post(self, *args, **kwargs):
        file_metas = self.request.files["filename"]     # 獲取文件信息
        for meta in file_metas:
            file_name = meta['filename']                # 獲得他的文件名字
            file_names = os.path.join('static','img',file_name)
            with open(file_names,'wb') as up:           # 打開本地一個文件
                up.write(meta['body'])                  # body就是文件內(nèi)容,把他寫到本地

settings = {
    'template_path':'views',
    'static_path':'static',
    'static_url_prefix': '/statics/',
}

application = tornado.web.Application([
    (r'/index',IndexHandler)
],**settings)

if __name__ == '__main__':
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

start.py

注:下面所有的實例用相同的python代碼都能實現(xiàn),只需要改前端代碼,python代碼文件名為start.py

tornado 生成隨機驗證碼

用python生成隨機驗證碼需要借鑒一個插件,和一個io模塊,實現(xiàn)起來也非常容易,當然也需要借鑒session來判斷驗證碼是否錯誤,下面寫一段用戶登錄驗證帶驗證碼的,再看下效果,插件必須和執(zhí)行文件必須放在更目錄下

Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import tornado.web
import tornado.ioloop

container = {}
class Session:
    def __init__(self, handler):
        self.handler = handler
        self.random_str = None

    def __genarate_random_str(self):
        import hashlib
        import time
        obj = hashlib.md5()
        obj.update(bytes(str(time.time()), encoding='utf-8'))
        random_str = obj.hexdigest()
        return random_str

    def __setitem__(self, key, value):
        # 在container中加入隨機字符串
        # 定義專屬于自己的數(shù)據(jù)
        # 在客戶端中寫入隨機字符串
        # 判斷,請求的用戶是否已有隨機字符串
        if not self.random_str:
            random_str = self.handler.get_cookie('__session__')
            if not random_str:
                random_str = self.__genarate_random_str()
                container[random_str] = {}
            else:
                # 客戶端有隨機字符串
                if random_str in container.keys():
                    pass
                else:
                    random_str = self.__genarate_random_str()
                    container[random_str] = {}
            self.random_str = random_str # self.random_str = asdfasdfasdfasdf

        container[self.random_str][key] = value
        self.handler.set_cookie("__session__", self.random_str)

    def __getitem__(self, key):
        # 獲取客戶端的隨機字符串
        # 從container中獲取專屬于我的數(shù)據(jù)
        #  專屬信息【key】
        random_str =  self.handler.get_cookie("__session__")
        if not random_str:
            return None
        # 客戶端有隨機字符串
        user_info_dict = container.get(random_str,None)
        if not user_info_dict:
            return None
        value = user_info_dict.get(key, None)
        return value


class BaseHandler(tornado.web.RequestHandler):
    def initialize(self):
        self.session = Session(self)


class LoginHandler(BaseHandler):
    def get(self, *args, **kwargs):
        self.render('login.html' ,state = "")

    def post(self, *args, **kwargs):
        username = self.get_argument('username')
        password = self.get_argument('password')
        code =self.get_argument('code')
        check_code = self.session['CheckCode']
        if username =="zhangyanlin" and password == "123" and code.upper() == check_code.upper():
            self.write("登錄成功")
        else:
            self.render('login.html',state = "驗證碼錯誤")

class CheckCodeHandler(BaseHandler):
    def get(self, *args, **kwargs):
        import io
        import check_code
        mstream = io.BytesIO()
        img,code = check_code.create_validate_code()
        img.save(mstream,"GIF")
        self.session['CheckCode'] =code
        self.write(mstream.getvalue())


settings = {
    'template_path':'views',
    'cookie_secret': "asdasd",
}

application = tornado.web.Application([
    (r'/login',LoginHandler),
    (r'/check_code',CheckCodeHandler)
],**settings)

if __name__ == '__main__':
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

start.py

Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>驗證碼</title>
</head>
<body>
    <form action="/login" method="post">
        <p>用戶名: <input type="text" name="username"> </p>
        <p>密碼: <input type="password" name="password"> </p>
        <p>驗證碼: <input type="text" name="code"><img src="/check_code" onclick="ChangeCode();" id = "checkcode"></p>
        <input type="submit" value="submit"> <span>{{state}}</span>
    </form>
<script type="text/javascript">  //當點擊圖片的時候,會刷新圖片,這一段代碼就可以實現(xiàn)
    function ChangeCode() {
        var code = document.getElementById('checkcode');
        code.src += "?";
    }
</script>
</body>
</html>

login.html

效果圖如下:

Python學習筆記_進階篇(一)_淺析tornado web框架,Python,python,學習,筆記

插件下載地址:猛擊這里文章來源地址http://www.zghlxwxcb.cn/news/detail-664357.html

到了這里,關(guān)于Python學習筆記_進階篇(一)_淺析tornado web框架的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務器費用

相關(guān)文章

  • Python學習之路-爬蟲進階:爬蟲框架運行

    安裝框架的目的 利用setup.py將框架安裝到python環(huán)境中,在編寫爬蟲時候,作為第三方模塊來調(diào)用 框架安裝第一步:完成 setup.py 的編寫 以下代碼相當于一個模板,只用更改name字段出,改為對應的需要安裝的模塊名稱就可以,比如這里是:scrapy_plus 將setup.py文件放到scrapy_plus的

    2024年02月19日
    瀏覽(20)
  • 【0基礎入門Python Web筆記】四、python 之計算器的進階之路

    【0基礎入門Python Web筆記】四、python 之計算器的進階之路

    一、python 之基礎語法、基礎數(shù)據(jù)類型、復合數(shù)據(jù)類型及基本操作 二、python 之邏輯運算和制流程語句 三、python 之函數(shù)以及常用內(nèi)置函數(shù) 現(xiàn)在的實戰(zhàn)需求: 計算出任意兩個數(shù)字的加法之和 可以通過一下代碼直接計算出a和b之和: 以上代碼只需要修改a和b的值,就可以輕松計算

    2024年02月11日
    瀏覽(22)
  • streamlit (python構(gòu)建web可視化框架)筆記

    streamlit (python構(gòu)建web可視化框架)筆記

    pip install streamlit 創(chuàng)建一個python文件 demo.py ,使用命令行運行在瀏覽器上 streamlit run demo.py 。 官方文檔 Streamlit documentation 中文文檔 可參考博客1-專欄 streamlit 提供了基于 python 的 web應用程序框架 ,以高效靈活的方式 可視化數(shù)據(jù) 。主要功能 streamlit 對數(shù)據(jù)可視化渲染,表格、地

    2023年04月26日
    瀏覽(26)
  • 【Python】Streamlit庫學習:一款好用的Web框架

    【Python】Streamlit庫學習:一款好用的Web框架

    ?Streamlit是一個基于tornado框架的快速搭建Web應用的Python庫,封裝了大量常用組件方法,支持大量數(shù)據(jù)表、圖表等對象的渲染,支持網(wǎng)格化、響應式布局。簡單來說,可以讓不了解前端的人搭建網(wǎng)頁。 相比于同類產(chǎn)品PyWebIO,Streamlit的功能更加全面一些。 官方文檔:https://doc

    2024年02月01日
    瀏覽(24)
  • Python學習筆記_進階篇(四)_django知識(三)

    本章內(nèi)容: Django 發(fā)送郵件 Django cookie Django session Django CSRF 我們常常會用到一些發(fā)送郵件的功能,比如有人提交了應聘的表單,可以向HR的郵箱發(fā)郵件,這樣,HR不看網(wǎng)站就可以知道有人在網(wǎng)站上提交了應聘信息。今天我們嘗試用django發(fā)送郵件做嘗試 1、配置相關(guān)參數(shù)settings 往

    2024年02月11日
    瀏覽(30)
  • Python學習筆記_進階篇(二)_django知識(一)

    Python學習筆記_進階篇(二)_django知識(一)

    本章簡介: Django 簡介 Django 基本配置 Django url Django view Django 模板語言 Django Form Django是一個開放源代碼的Web應用框架,由Python寫成。采用了MVC的軟件設計模式,即模型M,視圖V和控制器C。它最初是被開發(fā)來用于管理勞倫斯出版集團旗下的一些以新聞內(nèi)容為主的網(wǎng)站的。并于

    2024年02月12日
    瀏覽(22)
  • Python學習筆記_進階篇(三)_django知識(二)

    本章內(nèi)容 Django model django默認支持sqlite,mysql, oracle,postgresql數(shù)據(jù)庫。 1 sqlite django默認使用sqlite的數(shù)據(jù)庫,默認自帶sqlite的數(shù)據(jù)庫驅(qū)動 引擎名稱:django.db.backends.sqlite3 2mysql 引擎名稱:django.db.backends.mysql 1、配置文件中sqlite 2、配置文件中mysql 注:由于Django內(nèi)部連接MySQL時使用的

    2024年02月12日
    瀏覽(19)
  • web自動化框架:selenium學習使用操作大全(Python版)

    web自動化框架:selenium學習使用操作大全(Python版)

    Selenium需要瀏覽器驅(qū)動程序才能與所選瀏覽器交互。例如,F(xiàn)irefox需要安裝geckodriver。確保它在PATH中。 主流瀏覽器驅(qū)動下載地址如下: 瀏覽器 驅(qū)動名稱 打開方式及注意事項 地址 Chrome chromedriver driver = webdriver.Chrome() 下載瀏覽器對應版本的chromedriver.exe 一定要創(chuàng)建對象,不然打

    2024年02月11日
    瀏覽(25)
  • [學習筆記]python的web開發(fā)全家桶(ing)

    [學習筆記]python的web開發(fā)全家桶(ing)

    源學習視頻 目的:開發(fā)一個平臺(網(wǎng)站) 前端開發(fā):HTML、CSS、JavaScript Web框架:接收請求并處理 MySQL數(shù)據(jù)庫:存儲數(shù)據(jù)地方 快速上手: 基于Flask Web框架讓你快速搭建一個網(wǎng)站出來。 深入學習: 基于Django框架(主要) 老師在P2的26分22秒使用的畫圖軟件是Excalidraw 2.4.1 div和span div

    2024年02月04日
    瀏覽(28)
  • 【Python】Web學習筆記_flask(4)——鉤子函數(shù)

    【Python】Web學習筆記_flask(4)——鉤子函數(shù)

    鉤子函數(shù)可以用來注冊在請求處理的不同階段執(zhí)行出 Flask的請求鉤子指的是在執(zhí)行視圖函數(shù)前后執(zhí)行的一些函數(shù), 之前是有4種,但是? before_first_request已經(jīng)被刪除了,使用時會報錯 before_request:在每次請求前執(zhí)行,比如校驗權(quán)限,也可以用來記錄用戶最后的在線時間 after_r

    2024年02月14日
    瀏覽(23)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包