在《Sanic框架介紹》一節中的簡單示例中,路由函式test()
有一個引數request
,它是一個Request
物件,包含了客戶端(瀏覽器)發過來的HTTP請求的各類資料。
Sanic Request
物件的屬性
(1)json
:JSON格式資料
當客戶端POST來的資料是json格式時,可以通過request.json
來訪問:
from sanic import response
@app.route('/json', methods=['POST'])
async def post_json(request):
return response.json({"received": request.json})
(2)args
(字典):查詢字串變數
查詢字串變數就是說URL中問號?
及其後面的部分,比如,?name=jim&age=12
。這樣帶查詢變數的URL被解析後,args
字典就是這樣的:{'name':['jim'], 'age': ['12']}
。request物件的屬性query_string
就是未解析的字串值:name=jim&age=12
。該屬性提供了預設的解析查詢變數的策略,稍微我們介紹如何改變解析策略。
from sanic import response
@app.route('/args')
async def args(request):
return response.json({
"parsed": True,
"args": request.args,
"url": request.url,
"query_string": request.query_string,
})
(3)query_args
(列表)
該屬性提供了另外一種url引數的形式,它是元組(key, value)
的列表。該屬性提供了預設的解析查詢變數的策略,稍微我們介紹如何改變解析策略。
對於前面的URL查詢變數?name=jim&age=12
,對應的query_args
列表就是:
[('name', 'jim'), ('age', '12')]
如果同一個key對應多個value的情況?name=jim&age=12&name=tom
,對應的query_args
就是:
[('name', 'jim'), ('age', '12'), ('name', 'tom')]
Sanic 18.12 版本已經沒有 query_args 這個屬性
下面看具體程式碼來理解args
等查詢變數:
from sanic import Sanic
from sanic.response import json
app = Sanic()
@app.route('/args')
async def test(request):
return json({
"parsed": True,
"url": request.url,
"query_string": request.query_string,
"args": request.args,
"raw_args": request.raw_args,
# "query_args": request.query_args,
})
if __name__ == '__main__':
app.run(host='127.0.0.1', port=8888)
訪問這個web應用的輸出是:
{
"parsed": true,
"url": "http://127.0.0.1:8888/args?name=jim&age=12&name=tom",
"query_string": "name=jim&age=12&name=tom",
"args": {
"name": [
"jim",
"tom"
],
"age": [
"12"
]
},
"raw_args": {
"name": "jim",
"age": "12"
}
}
注意 raw_args
字典的value不是列表,而是args
字典中value的第一個值。這個屬性將來會被棄用。
(4)files
(字典):擁有name、body和type的檔案物件的字典
客戶端(瀏覽器)上傳的檔案包含在Form data中,files
字典的key是Form物件中檔案物件的名稱(不是檔名),這個檔案物件有name(檔名)、body(檔案資料)和type(檔案型別)三個屬性。
from sanic import Sanic
from sanic import response
app = Sanic()
@app.route('/')
async def index(request):
html = ('<html><body>'
'<form action="/files" method="post" enctype="multipart/form-data">'
'<input type="file" name="file1" /> <br />'
'<input type="file" name="file2" /> <br />'
'<input type="submit" value="Upload" />'
'</form>'
'</body></html>')
return response.html(html)
@app.route("/files", methods=['POST'])
async def post_json(request):
test_file = request.files.get('file1')
file_parameters = {
'body': len(test_file.body),
'name': test_file.name,
'type': test_file.type,
}
return response.json({
"received": True,
"file_object_names": request.files.keys(),
"test_file_parameters": file_parameters
})
if __name__ == '__main__':
app.run(host='127.0.0.1', port=8888)
執行上面這個web應用,並用瀏覽器開啟http://127.0.0.1:8888/
這個地址,可以看到一個簡單的上傳介面,需要選擇兩個檔案,然後點選“Upload”,就可以看到這個web應用返回的json資料:
// 20190321203852
// http://127.0.0.1:8888/files
{
"received": true,
"file_object_names": [
"file1",
"file2"
],
"test_file_parameters": {
"body": 33759,
"name": "ft-generator.jpg",
"type": "image/jpeg"
}
}
注意 從結果可以看出,requests.files.keys()
是網頁html中input
的name
,不是檔名。
(5)form
(字典):以POST方式傳遞的form變數
在上面files
例子中的網頁html部分加一行:
<input type="text" name="title" /> <br />
在post_json()
函式的返回json裡面加上request.form
,就可以看到request.form
的內容了:
{
"received": true,
"form": {
"title": [
"猿人學Python"
]
},
"file_object_names": [
"file1",
"file2"
],
"test_file_parameters": {
"body": 33759,
"name": "ft-generator.jpg",
"type": "image/jpeg"
}
}
(6)body
(位元組串):POST的原始資料。
這個屬性允許我們得到request的原始資料。
(7)headers
(字典):包含請求頭(headers)的不區分大小寫的字典。
(8)method
(字串):HTTP請求的方法,比如GET, POST
等。
(9)ip
(字串):客戶端(瀏覽器)的IP地址。
(10)port
(字串):客戶端(瀏覽器)的埠地址。
(11)socket
(元組):客戶端(瀏覽器)的(IP, port)
(12)app
:正在處理該request的Sanic應用物件的引用。當我們在blueprint檔案裡面或其它模組需要使用全域性的app
時可以通過request.app
來訪問它。
以下都是字串屬性:
(13)url
:請求的完整URL。
(14)scheme
:請求的URL scheme:http
或https
。
(15)host
:請求的host:127.0.0.1:8888
。
(16)path
:請求的路徑path: 比如/files
。
(17)query_string
:請求的查詢字串,name=jim&age=12
或空字串''
。
(18)uri_template
:路由處理器匹配的模板:/posts/<id>/
。
(19)token
授權header的值,,比如Basic YWRtaW46YWRtaW4=
。
Sanic Request使用get
和getlist
訪問值
request的屬性中是字典的,其實是dict
的一個子類RequestParameters
。它與內建字典不同的是get()
和getlist()
方法。
get(key, default=None)
跟dict
的get方法一樣。如果value是list時,只返回list的第一個元素。getlist(key, default=None)
返回整個list。
from sanic.request import RequestParameters
args = RequestParameters()
args['titles'] = ['Post 1', 'Post 2']
args.get('titles') # => 'Post 1'
args.getlist('titles') # => ['Post 1', 'Post 2']
總結
request
物件是web應用要處理的物件,它包含了客戶端(瀏覽器)的請求資料,通過它的各種屬性來訪問這些請求資料。
我的公眾號:猿人學 Python 上會分享更多心得體會,敬請關注。
***版權申明:若沒有特殊說明,文章皆是猿人學 yuanrenxue.com 原創,沒有猿人學授權,請勿以任何形式轉載。***