在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ Python/ 用 tornado 做網(wǎng)站 (3)
標(biāo)準(zhǔn)庫 (4)
如何成為 Python 高手
標(biāo)準(zhǔn)庫 (6)
標(biāo)準(zhǔn)庫 (3)
類(2)
Pandas 使用 (2)
xml
用 tornado 做網(wǎng)站 (5)
文件(1)
練習(xí)
列表(3)
從小工到專家
除法
錯誤和異常 (2)
函數(shù)(1)
用 tornado 做網(wǎng)站 (7)
為做網(wǎng)站而準(zhǔn)備
函數(shù)練習(xí)
標(biāo)準(zhǔn)庫 (8)
Pandas 使用 (1)
回顧 list 和 str
字典(1)
用 tornado 做網(wǎng)站 (3)
字符串(1)
函數(shù)(2)
寫一個簡單的程序
將數(shù)據(jù)存入文件
語句(5)
SQLite 數(shù)據(jù)庫
集成開發(fā)環(huán)境(IDE)
集合(1)
類(1)
用 tornado 做網(wǎng)站 (6)
用 tornado 做網(wǎng)站 (2)
自省
語句(4)
錯誤和異常 (1)
用 tornado 做網(wǎng)站 (4)
集合(2)
列表(1)
標(biāo)準(zhǔn)庫 (1)
生成器
mysql 數(shù)據(jù)庫 (1)
第三方庫
實戰(zhàn)
運(yùn)算符
類(3)
字典(2)
語句(1)
數(shù)和四則運(yùn)算
語句(2)
文件(2)
MySQL 數(shù)據(jù)庫 (2)
電子表格
迭代器
mongodb 數(shù)據(jù)庫 (1)
特殊方法 (2)
特殊方法 (1)
字符編碼
編寫模塊
用 tornado 做網(wǎng)站 (1)
標(biāo)準(zhǔn)庫 (5)
函數(shù)(4)
類(5)
字符串(2)
關(guān)于 Python 的故事
函數(shù)(3)
字符串(4)
處理股票數(shù)據(jù)
常用數(shù)學(xué)函數(shù)和運(yùn)算優(yōu)先級
字符串(3)
為計算做準(zhǔn)備
多態(tài)和封裝
類(4)
迭代
語句(3)
錯誤和異常 (3)
分析 Hello
Python 安裝
標(biāo)準(zhǔn)庫 (2)
列表(2)
元組

用 tornado 做網(wǎng)站 (3)

數(shù)據(jù)傳輸

在已經(jīng)建立了前端表單之后,就要實現(xiàn)前端和后端之間的數(shù)據(jù)傳遞。在工程中,常用到一個被稱之為 ajax() 的方法。

關(guān)于 ajax 的故事,需要濃墨重彩,因為它足夠精彩。

ajax 是“Asynchronous Javascript and XML”(異步 JavaScript 和 XML)的縮寫,在它的發(fā)展歷程中,匯集了眾家貢獻(xiàn)。比如微軟的 IE 團(tuán)隊曾經(jīng)將 XHR(XML HttpRequest) 用于 web 瀏覽器和 web 服務(wù)器間傳輸數(shù)據(jù),并且被 W3C 標(biāo)準(zhǔn)采用。當(dāng)然,也有其它公司為 Ajax 技術(shù)做出了貢獻(xiàn),雖然它們都被遺忘了,比如 Oddpost,后來被 Yahoo!收購并成為 Yahoo! Mail 的基礎(chǔ)。但是,真正讓 Ajax 大放異彩的 google 是不能被忽視的,正是 google 在 Gmail、Suggest 和 Maps 上大規(guī)模使用了 Ajax,才使得人們看到了它的魅力,程序員由此而興奮。

技術(shù)總是在不斷進(jìn)化的,進(jìn)化的方向就是用著越來越方便。

回到上一節(jié)使用的 jQuery,里面就有 ajax() 方法,能夠讓程序員方便的調(diào)用。

ajax() 方法通過 HTTP 請求加載遠(yuǎn)程數(shù)據(jù)。

該方法是 jQuery 底層 AJAX 實現(xiàn)。簡單易用的高層實現(xiàn)見 $.get, $.post 等。$.ajax() 返回其創(chuàng)建的 XMLHttpRequest 對象。大多數(shù)情況下你無需直接操作該函數(shù),除非你需要操作不常用的選項,以獲得更多的靈活性。

最簡單的情況下,$.ajax() 可以不帶任何參數(shù)直接使用。

在上文介紹 Ajax 的時候,用到了一個重要的術(shù)語——“異步”,與之相對應(yīng)的叫做“同步”。我引用來自阮一峰的網(wǎng)絡(luò)日志中的通俗描述:

"同步模式"就是上一段的模式,后一個任務(wù)等待前一個任務(wù)結(jié)束,然后再執(zhí)行,程序的執(zhí)行順序與任務(wù)的排列順序是一致的、同步的;"異步模式"則完全不同,每一個任務(wù)有一個或多個回調(diào)函數(shù)(callback),前一個任務(wù)結(jié)束后,不是執(zhí)行后一個任務(wù),而是執(zhí)行回調(diào)函數(shù),后一個任務(wù)則是不等前一個任務(wù)結(jié)束就執(zhí)行,所以程序的執(zhí)行順序與任務(wù)的排列順序是不一致的、異步的。

"異步模式"非常重要。在瀏覽器端,耗時很長的操作都應(yīng)該異步執(zhí)行,避免瀏覽器失去響應(yīng),最好的例子就是 Ajax 操作。在服務(wù)器端,"異步模式"甚至是唯一的模式,因為執(zhí)行環(huán)境是單線程的,如果允許同步執(zhí)行所有 http 請求,服務(wù)器性能會急劇下降,很快就會失去響應(yīng)。

看來,ajax() 是前后端進(jìn)行數(shù)據(jù)傳輸?shù)闹匾巧?/p>

承接上一節(jié)的內(nèi)容,要是用 ajax() 方法,需要修改 script.js 文件內(nèi)容即可:

$(document).ready(function(){
    $("#login").click(function(){
        var user = $("#username").val();
        var pwd = $("#password").val();
        var pd = {"username":user, "password":pwd};
        $.ajax({
            type:"post",
            url:"/",
            data:pd,
            cache:false,
            success:function(data){
                alert(data);
            },
            error:function(){
                alert("error!");
            },
        });
    });
});

在這段代碼中,var pd = {"username":user, "password":pwd};意即將得到的 user 和 pwd 值,放到一個 json 對象中(關(guān)于 json,請閱讀《標(biāo)準(zhǔn)庫(8)》),形成了一個 json 對象。接下來就是利用 ajax() 方法將這個 json 對象傳給后端。

jQuery 中的 ajax() 方法使用比較簡單,正如上面代碼所示,只需要 $.ajax() 即可,不過需要對立面的參數(shù)進(jìn)行說明。

  • type:post 還是 get。關(guān)于 post 和 get 的區(qū)別,可以閱讀:HTTP POST GET 本質(zhì)區(qū)別詳解
  • url:post 或者 get 的地址
  • data:傳輸?shù)臄?shù)據(jù),包括三種:(1)html 拼接的字符串;(2)json 數(shù)據(jù);(3)form 表單經(jīng) serialize() 序列化的。本例中傳輸?shù)木褪?json 數(shù)據(jù),這也是經(jīng)常用到的一種方式。
  • cache:默認(rèn)為 true,如果不允許緩存,設(shè)置為 false.
  • success:請求成功時執(zhí)行回調(diào)函數(shù)。本例中,將返回的 data 用 alert 方式彈出來。讀者是否注意到,我在很多地方都用了 alert() 這個東西,目的在于調(diào)試,走一步看一步,看看得到的數(shù)據(jù)是否如自己所要。也是有點(diǎn)不自信呀。
  • error:如果請求失敗所執(zhí)行的函數(shù)。

后端接受數(shù)據(jù)

前端通過 ajax 技術(shù),將數(shù)據(jù)已 json 格式傳給了后端,并且指明了對象目錄"/",這個目錄在 url.py 文件中已經(jīng)做了配置,是由 handlers 目錄的 index.py 文件的 IndexHandler 類來出來。因為是用 post 方法傳的數(shù)據(jù),那么在這個類中就要有 post 方法來接收數(shù)據(jù)。所以,要在 IndexHandler 類中增加 post(),增加之后的完善代碼是:

#!/usr/bin/env Python
# coding=utf-8

import tornado.web

class IndexHandler(tornado.web.RequestHandler):
    def get(self):
        self.render("index.html")

    def post(self):
        username = self.get_argument("username")
        password = self.get_argument("password")
        self.write(username)

在 post() 方法中,使用 get_argument() 函數(shù)來接收前端傳過來的數(shù)據(jù),這個函數(shù)的完整格式是 get_argument(name, default=[], strip=True),它能夠獲取 name 的值。在上面的代碼中,name 就是從前端傳到后端的那個 json 對象的鍵的名字,是哪個鍵就獲取該鍵的值。如果獲取不到 name 的值,就返回 default 的值,但是這個值默認(rèn)是沒有的,如果真的沒有就會拋出 HTTP 400。特別注意,在 get 的時候,通過 get_argument() 函數(shù)獲得 url 的參數(shù),如果是多個參數(shù),就獲取最后一個的值。要想獲取多個值,可以使用 get_arguments(name, strip=true)。

上例中分別用 get_argument() 方法得到了 username 和 password,并且它們都是 unicode 編碼的數(shù)據(jù)。

tornado.web.RequestHandler 的方法 write(),即上例中的 self.write(username),是后端向前端返回數(shù)據(jù)。這里返回的實際上是一個字符串,也可返回 json 字符串。

如果讀者要查看修改代碼之后的網(wǎng)站效果,最有效的方式先停止網(wǎng)站(ctrl+c),在從新執(zhí)行 Python server.py 運(yùn)行網(wǎng)站,然后刷新瀏覽器即可。這是一種較為笨拙的方法。一種靈巧的方法是開啟調(diào)試模式。是否還記得?在設(shè)置 setting 的時候,寫上 debug = True 就表示是調(diào)試模式了(參閱:用 tornado 做網(wǎng)站 (1))。但是,調(diào)試模式也不是十全十美,如果修改模板,就不會加載,還需要重啟服務(wù)。反正重啟也不麻煩,無妨啦。

看看上面的代碼效果:

http://wiki.jikexueyuan.com/project/start-learning-python/images/30501.png" alt="" />

這是前端輸入了用戶名和密碼之后,點(diǎn)擊 login 按鈕,提交給后端,后端再向前端返回數(shù)據(jù)之后的效果。就是我們想要的結(jié)果。

驗證用戶名和密碼

按照流程,用戶在前端輸入了用戶名和密碼,并通過 ajax 提交到了后端,后端借助于 get_argument() 方法得到了所提交的數(shù)據(jù)(用戶名和密碼)。下面要做的事情就是驗證這個用戶名和密碼是否合法,其體現(xiàn)在:

  • 數(shù)據(jù)庫中是否有這個用戶
  • 密碼和用戶先前設(shè)定的密碼(已經(jīng)保存在數(shù)據(jù)庫中)是否匹配

這個驗證工作完成之后,才能允許用戶登錄,登錄之后才能繼續(xù)做某些事情。

首先,在 methods 目錄中(已經(jīng)有了一個 db.py)創(chuàng)建一個文件,我命名為 readdb.py,專門用來存儲讀數(shù)據(jù)用的函數(shù)(這種劃分完全是為了明確和演示一些應(yīng)用方法,讀者也可以都寫到 db.py 中)。這個文件的代碼如下:

#!/usr/bin/env Python
# coding=utf-8

from db import *

def select_table(table, column, condition, value ):
    sql = "select " + column + " from " + table + " where " + condition + "='" + value + "'"
    cur.execute(sql)
    lines = cur.fetchall()
    return lines

上面這段代碼,建議讀者可以寫上注釋,以檢驗自己是否能夠?qū)⒁酝闹R融會貫通地應(yīng)用。恕我不再解釋。

有了這段代碼之后,就進(jìn)一步改寫 index.py 中的 post() 方法。為了明了,將 index.py 的全部代碼呈現(xiàn)如下:

#!/usr/bin/env Python
# coding=utf-8

import tornado.web
import methods.readdb as mrd

class IndexHandler(tornado.web.RequestHandler):
    def get(self):
        self.render("index.html")

    def post(self):
        username = self.get_argument("username")
        password = self.get_argument("password")
        user_infos = mrd.select_table(table="users",column="*",condition="username",value=username)
        if user_infos:
            db_pwd = user_infos[0][2]
            if db_pwd == password:
                self.write("welcome you: " + username)
            else:
                self.write("your password was not right.")
        else:
            self.write("There is no thi user.")

特別注意,在 methods 目錄中,不要缺少了__init__.py文件,才能在 index.py 中實現(xiàn) import methods.readdb as mrd。

代碼修改到這里,看到的結(jié)果是:

http://wiki.jikexueyuan.com/project/start-learning-python/images/30502.png" alt="" />

這是正確輸入用戶名(所謂正確,就是輸入的用戶名和密碼合法,即在數(shù)據(jù)庫中有該用戶名,且密碼匹配),并提交數(shù)據(jù)后,反饋給前端的歡迎信息。

http://wiki.jikexueyuan.com/project/start-learning-python/images/30503.png" alt="" />

如果輸入的密碼錯誤了,則如此提示。

http://wiki.jikexueyuan.com/project/start-learning-python/images/30504.png" alt="" />

這是隨意輸入的結(jié)果,數(shù)據(jù)庫中無此用戶。

需要特別說明一點(diǎn),上述演示中,數(shù)據(jù)庫中的用戶密碼并沒有加密。關(guān)于密碼加密問題,后續(xù)要研究。


總目錄   |   上節(jié):用 tornado 做網(wǎng)站 (2)   |   下節(jié):用 tornado 做網(wǎng)站 (4)

如果你認(rèn)為有必要打賞我,請通過支付寶:qiwsir@126.com,不勝感激。