文章目錄
- 什麼是flask架構:
- flask的安裝:
- flask的基本使用:
-
- 執行個體:
-
- 執行個體解析:
-
- 第一步:導包:
- 第二步:執行個體化Flask
- 第三.四.五步:route和視圖函數
- 第六.七步:判斷是否在本檔案運作
- DEBUG模式:
-
- DEBUG的作用:
- 開啟DEBUG的方式:
-
- 第一種:app.run(debug=True)
- 第二種:app.debug=True
- 第三種:建立對象
- 第四種:建立檔案
- 響應json資料的兩種方法:
-
- 方法一:
- 方法二 (推薦使用):
- 傳回前端頁面(render_template)
-
- 執行個體:
- templates目錄:
- 關于render_template()前端檔案名高亮和提示的解決辦法:
- 頁面重定向(redirect)
-
- 執行個體:
-
- 可以帶參數的頁面跳轉
- 不能帶參數的頁面跳轉
- 抛出異常,捕捉異常(abort)
-
- 常見的狀态碼:
- 抛出異常
- 轉換器(BaseConverter)
-
- 詳情:
- 執行個體:
- 請求鈎子:
-
- 伺服器開啟的第一個指令:
- 每次請求會先執行的視圖函數:
- 每次請求後會執行的視圖函數
- request請求對象
-
- 獲得get請求中的資料
- 獲得post請求中的資料
- 建立響應對象(make_response)
- cookie
-
- 建立cookie:
- 獲得cookie:
- 删除cookie
- 執行個體:
- session
-
- 建立session
- 獲得session
- 删除session
- 設定session過期時間:
- 執行個體
- 以腳本的方式運作(Manager):
-
- 下載下傳包:
- 建立腳本管理對象
- 使用腳本管理器對象啟動程式
- 再終端上執行腳本指令
- 執行個體:
- 解決腳本方式運作不能右鍵直接運作的辦法
- 跨站請求僞造(CSRF)
-
- 什麼是跨站請求僞造:
- 解決方法一(form表單添加随機值):
-
- 執行個體:
- 解決辦法二:(設定請求頭):
什麼是flask架構:
Flask是一個Python編寫的Web 微架構,讓我們可以使用Python語言快速實作一個網站或Web服務。
flask的安裝:
需要在虛拟環境中下載下傳,進入虛拟環境中的Scripts執行active,(注意下載下傳 flask 要注意版本号)
pip install flask==0.10.1
flask的基本使用:
執行個體:
from flask import Flask,request,render_template
app = Flask(__name__)
@app.route("/index/",methods=["get","post"])
def index():
return render_template("index.html")
if __name__ == '__main__':
app.run()
執行個體解析:
第一步:導包:
from flak import Flak
from:導入flak這個檔案 import 是目前檔案中沒有Flak 這個類 就會使用flak 檔案中的Flask這個類
第二步:執行個體化Flask
app=Flask(__name__)
app是Flask的執行個體,它接收包或者子產品的名字作為參數,但一般都是傳遞__name__ 是用于判斷是那個檔案在調用
第三.四.五步:route和視圖函數
@app.route("/index")
def index():
return "hello world!"
使用app.route裝飾器會将URL和執行的視圖函數的關系儲存到app.url_map屬性上。
處理URL和視圖函數的關系的程式就是路由,這裡的視圖函數就是index
通路i ndex 就會執行視圖函數
第六.七步:判斷是否在本檔案運作
if __name__ == '__main__':
app.run()
判斷操作者是import這個py還是直接運作這個py,如果是直接運作就會執行app.run()
DEBUG模式:
DEBUG的作用:
debug模式的情況下可以抛出詳細異常資訊,如圖:
未開啟BEBUG:

如果運作的時候代碼報錯了,是不會提示詳細錯誤的,隻會報伺服器内部錯誤
開啟DEBUG:
開啟debug模式,可以檢視到詳細錯誤,此外,在debug模式下,修改了代碼flask會自動重新開機,這樣就不用每次修改了代碼手動重新運作了
開啟DEBUG的方式:
第一種:app.run(debug=True)
第二種:app.debug=True
第三種:建立對象
第四種:建立檔案
在目前目錄下建立一個 config.ini的檔案寫入 DEBUG=True如圖
在使用app.config.from_pyfile()
響應json資料的兩種方法:
方法一:
使用python中的系統庫json
文法:
res=json.dumps(date)
date是字典資料類型
執行個體:
from flask import Flask
import json
app=Flask(__name__)
@app.route('/',methods=["get",'post'])
def index():
date={
"name":"laowang",
"age":18
}
res=json.dumps(date)
return res
if __name__=='__main__':
app.run(debug=True)
這樣雖然是把json資料傳出去了,但是在響應頭中的Content-Type中是文本類型還得修改響應頭是比較麻煩的我們在一起來看第二種方法
方法二 (推薦使用):
是使用Flask架構中的jsonify
導包方式為:
from flask import Flask,jsonify
執行個體:
from flask import Flask,jsonify
app=Flask(__name__)
@app.route('/',methods=["get",'post'])
def index():
date={
"name":"laowang",
"age":18
}
return jsonify(date)
if __name__=='__main__':
app.run(debug=True)
我們可以在控制台看到傳回的資料類型也為json了
傳回前端頁面(render_template)
在某些情況下我們是需要傳回前端頁面
而前端頁面我們都是放在templates的檔案目錄下的
目錄的名字最好是templates 因為flask架構中是對templates 目錄做了處理的
一起來看看使用方法吧
導包:
from flask import Flask,render_template
文法:
render_template("index.html")
執行個體:
from flask import Flask,render_template
app=Flask(__name__)
@app.route('/',methods=["get",'post'])
def index():
return render_template("index.html")
if __name__=='__main__':
app.run(debug=True)
templates目錄:
關于render_template()前端檔案名高亮和提示的解決辦法:
頁面重定向(redirect)
當我們進入一個網站的時候需要我們登入就可以用到頁面跳轉(redirect)
使用方法如下:
導包:
from flask import Flask,redirect,url_for
文法:
redirect("/login") login可以是個視圖函數名也可也是位址
或者:
redirect(url_for("login")) login必須是個視圖函數
執行個體:
可以帶參數的頁面跳轉
from flask import Flask,redirect,url_for
app=Flask(__name__)
@app.route('/',methods=["get",'post'])
def index():
return redirect(url_for("login",name="laowang"))
@app.route('/login/<name>',methods=["get",'post'])
def login(name):
return name+"通路我了"
if __name__=='__main__':
app.run(debug=True)
不能帶參數的頁面跳轉
from flask import Flask,redirect,url_for
app=Flask(__name__)
@app.route('/',methods=["get",'post'])
def index():
return redirect("login")
@app.route('/login',methods=["get",'post'])
def login():
return "通路我了"
if __name__=='__main__':
app.run(debug=True)
抛出異常,捕捉異常(abort)
常見的狀态碼:
200:正常
301:頁面重定向
404:資源找不到
405:請求方式不正确
505:伺服器異常
抛出異常
導包
from flask import Flask,abort
文法:
abort(狀态碼)
轉換器(BaseConverter)
詳情:
當請求位址中有這樣的參數時我們是需要校驗的
會導入一個包:
from werkzeug.routing import BaseConverter
導包之後還需要建立一個類:
# 繼承 BaseConverter
class ReConverter(BaseConverter):
def __init__(self,map,*args):
# map是做過處理的是以還是讓父類來處理map
super().__init__(map)
# 接收 *args傳進來的第一個參數, *args傳進來的參數會自動生成一個元組
self.regex=args[0]
# 執行個體化類 ["re"]相當于取的一個别名
app.url_map.converters["re"]=ReConverter
#寫入正則判斷是否是合理的
@app.route('/<re("[0-9]{4}"):num>',methods=["get",'post'])
執行個體:
from flask import Flask
from werkzeug.routing import BaseConverter
app=Flask(__name__)
# 繼承 BaseConverter
class ReConverter(BaseConverter):
def __init__(self,map,*args):
# map是做過處理的是以還是讓父類來處理map
super().__init__(map)
# 接收 *args傳進來的第一個參數, *args傳進來的參數會自動生成一個元組
self.regex=args[0]
# 執行個體化類 ["re"]相當于取的一個别名
app.url_map.converters["re"]=ReConverter
@app.route('/<re("[0-9]{4}"):num>',methods=["get",'post'])
def index(num):
return "你帶着 %s 通路到我了"% num,600
if __name__=='__main__':
app.run(debug=True)
請求鈎子:
伺服器開啟的第一個指令:
@app.before_first_request
def before_first_request():
print("服務開啟的第一個指令")
return "hello World!"
每次請求會先執行的視圖函數:
@app.before_request
def before_request():
print("每次請求會先運作我")
每次請求後會執行的視圖函數
@app.after_request
def after_request(response):
print("每次請求後才會運作我")
return response
request請求對象
不管是get或者是post請求都是以鍵值段的方式傳,如果沒有預設值是為none
獲得get請求中的資料
導包:
from flask import Flask,request
文法:
request.args.get("name",1)
獲得post請求中的資料
request.form.get("name",1)
建立響應對象(make_response)
在一些時候是需要響應對象,文法如下
make_response(render_template("login.html"))
redirect 這是不需要響應對象的
cookie
浏覽器和伺服器是無狀态的,無狀态可以想象成這次登入賬号,下次還得重新登入
然而呢,我們想要的是這次登入了下次不登入,就得實作狀态保持cookie
cookie是将資料存放在本地的,下次請求會攜帶上cookie,就實作了狀态保持了
建立cookie:
文法:
response.set_cookie("name",name,max_age=60*60*24)
因為是響應的時候才把cookie寫入本地檔案是以必須要個響應對象,第一個name是鍵,第二個name才是值,第三個max_age是cookie的存活時間
獲得cookie:
導包:
from flask import Flask,request
文法:
request.cookies.get("name")
删除cookie
reponse.delete_cookie("name")
删除cookie是在響應對象中删除
執行個體:
from flask import Flask,request,make_response,redirect,render_template,url_for
app=Flask(__name__)
@app.route('/',methods=["get",'post'])
def index():
"""
根目錄
"""
# 如果有cookie就表示以前登入過
name=request.cookies.get("name")
# 判斷name為空的時候就讓頁面重定向到登入頁面
if not name :
return redirect('/login')
# 跳轉到index.html頁面
return render_template("index.html",name=name)
# 登入界面 并接收兩種處理方式
@app.route('/login',methods=["get",'post'])
def login():
# render_template 需要傳回對象是以導包 make_response
res = make_response(render_template("login.html"))
# 判斷是否是post請求
if request.method=="POST":
# 從post請求中 獲得name的值
name = request.form.get("name")
# 有post 請求 就跳轉到根位址
response = make_response(redirect("/"))
# 從響應對象設定cookie "name"為鍵 name 為值 max_age是設定cookie的有效時間
response.set_cookie("name",name,max_age=60*60*24)
# 響應respoonse對象
return response
# 響應res對象
return res
# 位址為del進入delete_cookie視圖函數
@app.route("/del")
def delete_cookie():
# 響應對象為頁面跳轉login
res=redirect(url_for("login"))
# 删除cookie
res.delete_cookie("name")
return res
if __name__=='__main__':
app.run(debug=True)
session
session是基于cookie的,cookie資料存放在用戶端本地的是以安全系數不是很高,session
是将資料存在伺服器的,把鍵(key)給到用戶端,用戶端通路的時候隻需要帶上鍵(key)就能訪
問了
導包:
from flask import Flask,sessione
建立session
文法:
session["name"]="laowang"
獲得session
文法:
session.get("name")
删除session
文法:
session.pop("name")
設定session過期時間:
from datetime import timedelta
session.permanent = True # 預設是31天
app.permanent_session_lifetime = timedelta(minutes=5) # 指定session具體的過期時間
執行個體
# 導入子產品:
from flask import Flask, session
app=Flask(__name__)
# 加鹽:
app.config['SECRET_KEY'] = 'fasf' # 加鹽是讓你的原始資料加上這個你随意寫入的(一般要用個加密算法得出的結果)的資料再加密,確定資料的安全性
# 設定session
session['name'] = 'zxc'
# 讀取session
name = session.get(‘name’)
name = session['name']
# 删除session
session.pop('name')
# 設定session過期時間:
# 過期時間, 通過cookie實作的
from datetime import timedelta
session.permanent = True # 預設是31天
app.permanent_session_lifetime = timedelta(minutes=5) # 指定session具體的過期時間
以腳本的方式運作(Manager):
開發中我們可以用pycharm來運作,但是部署到伺服器就沒有pycharm來啟動了,需要以
腳本的方式來運作python檔案,需要用到flask-script中的Manager
下載下傳包:
pip install flask-script -i https://pypi.tuna.tsinghua.edu.cn/simple
建立腳本管理對象
manager = Manager(app)
使用腳本管理器對象啟動程式
manager.run()
再終端上執行腳本指令
python demo.py runserver -p 5001 -d # -d是開啟調試模式
執行個體:
from flask import Flask, render_template, session, request, redirect, url_for
from flask_script import Manager
app = Flask(__name__)
app.config["SECRET_KEY"] = "123"
manager = Manager(app)
@app.route("/", methods=["GET", "POST"])
def index():
if session.get("name") is not None:
name = session.get("name")
return render_template("index.html", name=name)
return redirect("/login")
@app.route("/login", methods=["GET", "POST"])
def login():
if request.method == "POST":
session["name"] = request.form.get("name")
return redirect(url_for("index"))
return render_template("login.html")
@app.route("/del", methods=["GET", "POST"])
def delete():
session.pop("name")
return render_template("del.html")
if __name__ == "__main__":
manager.run()
解決腳本方式運作不能右鍵直接運作的辦法
我們設定腳本運作的方式後我們右鍵運作會出現以下提示:
而且報錯後也不能快速的定位到有問題的那行代碼:
解決辦法:
跨站請求僞造(CSRF)
什麼是跨站請求僞造:
CSRF是Cross Site Request Forgery的縮寫,翻譯過來就是跨站請求僞造。
意思是:從一個網站A中發起一個到網站B的請求,而這個請求是經過了僞裝的,僞裝
操作達到的目的就是讓請求看起來像是從網站B中發起的,也就是說,讓B網站所在的服
務器端誤以為該請求是從自己網站發起的,而不是從A網站發起的
解決方法一(form表單添加随機值):
在登入網站A的時候把伺服器産生的字元串随機數寫入cookie,form中寫入一個隐藏的import标簽 值就是寫入cookie的值,在送出表單的時候驗證cookie中的值是否很隐藏表單的值是否相同.
執行個體:
import base64
import os
from flask import Flask,request,render_template,redirect,url_for,make_response
app=Flask(__name__)
@app.route('/',methods=["get",'post'])
def login():
"""
登入.接收使用者傳經來的參數,并寫入cookie
:return:
"""
# 判斷是否有post請求
if request.method=="POST":
# 擷取使用者傳進來的值
username=request.form.get("username")
pwd=request.form.get("password")
print(pwd,username)
# 判斷使用者.密碼是否為空
if not all([username,pwd]):
return redirect("/")
# 判斷使用者.密碼是否正确,正确寫入到cookie,頁面跳轉到下一個界面
if username=="laowang" and pwd=="123":
res=redirect("transfer")
res.set_cookie("name",username)
return res
return redirect("/")
# cookie中有相關資訊就免登入
name=request.cookies.get("username")
if name :
return redirect(url_for("transfer"))
# 渲染前端頁面
return render_template("temp_login.html")
@app.route('/transfer',methods=["get",'post'])
def transfer():
# 判斷cookie中是否有值
username = request.cookies.get("name")
if not username:
return redirect("/")
# 産生随機字元串,寫入cookie,form表單中,防止跨站請求僞造
cookie_csrf = set_random()
res = make_response(render_template("temp_transfer.html", form_csrf=cookie_csrf))
res.set_cookie("csrf", cookie_csrf)
# 判斷是否有post請求
if request.method=="POST":
# 獲得post請求的資料
to_account=request.form.get("to_account")
money=request.form.get("money")
form_csrf=request.form.get("form_csrf")
# 判斷post請求是否有空值
if not all([to_account, money,form_csrf]):
return redirect("/")
# 判斷cookie和表單中的随機值是否一緻
if not (cookie_csrf==form_csrf):
return "違法操作"
print("成功的向%s 轉入%s" %(username,money))
return "成功的向%s 轉入%s" %(username,money)
return res
def set_random():
return bytes.decode(base64.b64encode(os.urandom(48)))
if __name__=='__main__':
app.run(debug=True)
解決辦法二:(設定請求頭):
每次請求後将随機的值設定到cookie,請求頭獲得cookie