flask請求鈎子、HTTP響應、響應報文、重定向、手動返回錯誤碼、修改MIME類型、jsonify()方法 --


 

請求鈎子:

當我們需要對請求進行預處理和后處理時,就可以用Flask提供的回調函數(鈎子),他們可用來注冊在請求處理的不同階段執行的處理函數。這些請求鈎子使用裝飾器實現,通過程序實例app調用,以 before_request鈎子為例(請求之前),當你對一個函數附加了app.before_request裝飾器后,就會將這個函數注冊為before_request處理函數,每次執行請求前都會觸發所有before_request函數

 

Flask默認 實現的五種鈎子:

 

 

示例代碼:

定義了三個視圖函數 A,B,C,其中C使用了after_this_request鈎子,在網頁中請求url 為/C,會觸發C視圖函數,在執行該函數的流程是先進入before_first_requst鈎子,然后進入before_request鈎子,之后進入C函數內部注冊的after_this_request鈎子函數。

之后的after_requet和teardown_request在觸發響應條件時會執行。

 

@app.before_request
def before_request():
    print "before request"

@app.before_first_request
def before_first_request():
    print "before first request"

# @app.after_request
# def after_request(response):
#     print "after request"

@app.after_request
def per_request_callbacks(response):
    for func in getattr(g, 'call_after_request', ()):
        print "after request"
       
response = func(response)
    return response

@app.route('/A')
def A():
    return '<p> this is function A</p>'

@app.route('/B')
def B():
    return '<p>this is function B</p>'

@app.route('/C')
def C():
    @flask.after_this_request
    def after_this_request(response):
        print "after this request"
       
#raise ValueError
       
return response
    return "<p>after this request</p>"



if __name__ == '__main__':
    app.run(debug = True)

 

結果:

 

 

 

http響應

Flask程序中,客戶端的請求會觸發相應的視圖函數,獲取返回值作為響應的主題,最后生成完整的響應,即響應報文

 

響應報文:

響應報文有協議版本、狀態碼、原因短語、響應首部和響應主體組成

 

響應報文的首部包含一些關於響應和服務器的信息,這些內容有Flask生成,而我們在視圖函數中返回的內容即為響應報文中的主體內容。瀏覽器接收響應后,會把返回的響應主題解析並顯示 在瀏覽器窗口上。

 

HTTP狀態碼用來表示請求處理的結果

 

 

在Flask中生成響應

響應在Flask中使用Response對象表示 ,響應報文中的大部分內容有服務器處理,大多數情況下,我們只負責返主題內容。

 

Flask處理請求時會先判斷是否可以找到與請求URL相匹配的路由,如果沒有則返回404響應。如果有,則調用對應的視圖函數,視圖函數的返回值構成了響應報文的主題內容,正確返回時狀態碼默認為200,Flask會調用make_response()方法將視圖函數返回值轉換為響應對象。

 

完整的說,視圖函數可以返回最多有三個元素組成的元祖:響應主題、狀態碼、首部字段。其中首部字段可以為字典,或是兩元素元祖組成的列表([(‘Location’,’http://localhost:5000/hi’),(‘contentType’,’…’)])

 

flask請求成功時默認的響應碼是200

 

可以對請求指定不同的響應狀態碼:指定url為hi的請求的響應狀態碼為201

 

結果:

 

重定向

重定向可以通過修改30X響應的首部Location的字段的值來進行:

 

在視圖函數中,return語句后面用字典的形式指定Location的值,訪問的時候,會根據Location的值進行重定向

 

@app.route('/redirect')
def redirect():
    return "<p>This is a redirect pare</p>"

@app.route('/hello1')
def hello1():
    print "redirect..."
   
return '', 302, {'Location': 'http://127.0.0.1:5000/redirect'}

 

if __name__ == '__main__':
    app.run(debug = True)

 

結果:

 

 

訪問hello1路徑時,頁面進行了重定向,重定向的位置是首部中Location字段的URL

 

也可以通過Flask提供的redirect()函數來生成重定向響應

from flask import Flask,redirect

@app.route('/hello2')
def hello2():
    return redirect('http://localhost:5000/redirect')

if __name__ == '__main__':
    app.run(debug = True)

 

結果:

 

 

修改重定向redirect函數返回碼為303

@app.route('/hello2')
def hello2():
    return redirect('http://localhost:5000/redirect',303)

if __name__ == '__main__':
    app.run(debug = True)

 

結果:

 

 

程序內重定向到其他視圖函數

如果要在程序內重定向到其他視圖函數,可以在redirect()函數中使用url_for()函數生成目標URL,可以在響應首部的Location看到重定向的目標URL,重定向到其他視圖其實就是重定向到該視圖對應的url

 

from flask import Flask,redirect,url_for

@app.route('/hello3')
def hello3():
    return redirect(url_for('redirect'))#重定向到/redirect

@app.route('/redirect')
def redirect():
    return "<p>This is a redirect pare</p>"

if __name__ == '__main__':
    app.run(debug = True)

 

結果:

 

手動返回錯誤響應

大多數情況下,Flask會自動處理常見的錯誤響應。HTTP錯誤對應的異常類在Werkzeug的werkzeug.exceptions模塊中定義,拋出這些異常即可返回對應的錯誤響應。如果你想手動返回錯誤響應,可以使用Flask提供的abort()函數。

在abort()函數中傳入狀態碼即可返回對應的錯誤響應。

需要注意,abourt()函數被調用后,abort()函數之后的代碼不會被執行。

例子為手動返回404錯誤:

 

from flask import abort

@app.route('/404')
def not_found():
    abort(404)



if __name__ == '__main__':
    app.run(debug = True)

 

結果:

 

響應格式:

在http響應中,數據可以通過多種格式傳輸,我們會使用HTML格式,這也是Flask中的默認審核制。在特定的情況下,我們也會用其他格式。不同的響應數據格式需要設置不同的MIME類型,MIME類型在首部的Content-Type字段中定義,以默認的HTML類型為例 :

 

Content-Type:  text/html; charset=utf-8

 

MIME類型

MIME類型(又稱media type或content type)是一種用來表示文件類型的機制,它與文件擴展名相對應,可以讓客戶端區分不同的內容類型,並執行不同的操作。一般的格式為“類型名/子類型名”。其中子類型名一般為文件擴展名。比如HTML的MIME類型為”text/html”,png圖片的MIME類型為”image/png”。

 

如果想使用其他MIME類型,可以通過Flask提供的make_response()方法生成響應對象,傳入響應的主體作為參數,然后使用響應對象的mimetype屬性設置MIME類型,不需要設置字符集(charset)選項。

修改MIME類型:

from flask import make_response

@app.route('/foo')
def foo():
    response = make_response('Hello,World!')
    response.mimetype = 'text/plain'
   
return response

 

 

結果:

 

常用的數據格式(純文本、HTML、XML和JSON)對應的MIME類型

純文本的MIME類型:text/plain

HTML的MIME類型:text/html

XML的MIME類型:application/xml

JSON的MIME類型:application/json

 

Flask提供JSON的支持

Flask通過引入Python標准庫中的json模塊為程序提供了JSON支持。你可以直接從Flask中導入json對象,然后調用dumps()方法將字典、列表或元祖序列化為JSON字符串,在使用前面介紹的方法修改MIME類型,即可返回JSON響應

例如:

用json模塊把響應轉換為JSON

from flask import Flask,make_response,json

@app.route('/foo1')
def foo1():
    data={'name':'Sam Xia','gender':'male'}
    response = make_response(json.dumps(data))
    response.mimetype = 'application/json'
   
return response

if __name__ == '__main__':
    app.run(debug = True)

 

結果:

 

 

也可以jsonnify()方法轉換響應內容為JSON

不過我們一般並不直接使用json模塊的dumps()、load()等方法,因為Flask通過包裝這些方法提供了更方便的jsonify()函數。用jsonify()函數,我們進需要傳入數據或參數,他會把傳入的參數轉化成JSON字符串作為響應的主體,然后生成一個響應對象,並且設置正確的MIME類型。

例如:

@app.route('/foo3')
def foo3():
    return jsonify(name = 'Sam Xia',gender = 'make')

if __name__ == '__main__':
    app.run(debug = True)

 

結果:

 

jsonify()函數可以接收多種形式的參數。可以傳入如上邊的關鍵字參數,也可以像dumps()方法一樣傳入字段、列表或元祖,如:


from flask import jsonify

@app.route('/foo3')
def foo3():
    return jsonify({'name':'Sam Xia','gender' : 'make'})#傳入字典

if __name__ == '__main__':
    app.run(debug = True)

 

結果:

 

jsonify()函數可以自定義響應碼

 

from flask import jsonify

@app.route('/foo3')
def foo3():
    return jsonify(message = 'Error !'),500

 

if __name__ == '__main__':
    app.run(debug = True)

 

結果:

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM