Tornado——接收前端傳來的參數


接收前端傳來的參數

利用HTTP協議向服務器傳參的幾種途徑:

  • 查詢字符串(query string),形如key1=value1&key2=value2;
  • 請求體(body)中發送的數據,比如表單數據、json、xml;
  • 提取uri的特定部分,如/blogs/2016/09/0001,可以在服務器端的路由中用正則表達式截取;
  • 在http報文的頭(header)中增加自定義字段。

1. 獲取查詢字符串參數

get_query_argument(name, default=_ARG_DEFAULT, strip=True)

從請求的查詢字符串中返回指定參數name的值,如果出現多個同名參數,則返回最后一個的值。

default為設值未傳name參數時返回的默認值,如若default也未設置,則會拋出tornado.web.MissingArgumentError異常。

strip表示是否過濾掉左右兩邊的空白字符,默認為過濾。(當傳送密碼時可以將strip設置為False)

get_query_arguments(name, strip=True)

從請求的查詢字符串中返回指定參數name的值,注意返回的是list列表(即使對應name參數只有一個值)。若未找到name參數,則返回空列表[]。

strip同前,不再贅述。

2. 獲取請求體參數

get_body_argument(name, default=_ARG_DEFAULT, strip=True)

從請求體中返回指定參數name的值,如果出現多個同名參數,則返回最后一個的值。

default與strip同前,不再贅述。

get_body_arguments(name, strip=True)

從請求體中返回指定參數name的值,注意返回的是list列表(即使對應name參數只有一個值)。若未找到name參數,則返回空列表[]。

strip同前,不再贅述。

說明

對於請求體中的數據要求為字符串,且格式為表單編碼格式(與url中的請求字符串格式相同),即key1=value1&key2=value2,HTTP報文頭Header中的"Content-Type"為application/x-www-form-urlencoded 或 multipart/form-data。對於請求體數據為json或xml的,無法通過這兩個方法獲取。

3. 前兩類方法的整合

get_argument(name, default=_ARG_DEFAULT, strip=True)

從請求體和查詢字符串中返回指定參數name的值,如果出現多個同名參數,則返回最后一個的值。

default與strip同前,不再贅述。

get_arguments(name, strip=True)

從請求體和查詢字符串中返回指定參數name的值,注意返回的是list列表(即使對應name參數只有一個值)。若未找到name參數,則返回空列表[]。

strip同前,不再贅述。

說明

對於請求體中數據的要求同前。 這兩個方法最常用。

用代碼來看上述六中方法的使用:

# coding:utf-8
import tornado.web
import tornado.ioloop
import tornado.httpserver
import tornado.options

from tornado.web import url,RequestHandler
from tornado.options import define,options

tornado.options.define("port",default=8000,type=int,help="給個端口號唄")

class IndexHandler(RequestHandler):
    def post(self):
        # ====================== 獲取查詢字符串(query string,get請求發來的) ========================
		
        subject = self.get_query_argument("subject","python")    # name=subject的,默認值設為python,去除空格默認為True
        query_args = self.get_query_arguments("q")   # 獲取的為列表格式
        query_arg = self.get_query_argument("q")    # 只會獲取傳來的最后一個值
        
        # ====================== 獲取body傳來的表單 ====================== 
		
        body_args = self.get_body_arguments("b")    # 列表格式
        body_arg = self.get_body_argument("b")      # 只會獲取傳來的最后一個值

        # ====================== 前兩類方法的整合 ======================
		
        a_list = self.get_arguments("a")     # 獲取get和post請求發來的,列表形式
        a = self.get_argument("a")  # 獲取的是post方式發來的最后一個值,因為get是從請求頭發來的,先解析;post是請求體發來的,后解析
        

        self.write(str(a_list))     # 返回的都是unicode字符串



if __name__ == "__main__":
    tornado.options.parse_command_line()
    app = tornado.web.Application(
        [
        (r"/",IndexHandler),
        ],
        debug = True
    )
    
    http_server = tornado.httpserver.HTTPServer(app)    # 創建httpserver實例
    http_server.listen(options.port)		# 監聽端口
    tornado.ioloop.IOLoop.current().start()		# 開啟epoll

4. 關於請求的其他信息

RequestHandler.request 對象存儲了關於請求的相關信息,具體屬性有:

  • method HTTP的請求方式,如GET或POST;
  • host 被請求的主機名;
  • uri 請求的完整資源標示,包括路徑和查詢字符串;
  • path 請求的路徑部分;
  • query 請求的查詢字符串部分;
  • version 使用的HTTP版本;
  • headers 請求的協議頭,是類字典型的對象,支持關鍵字索引的方式獲取特定協議頭信息,例如:request.headers["Content-Type"]
  • body 請求體數據;
  • remote_ip 客戶端的IP地址;
  • files 用戶上傳的文件,為字典類型,型如:
{
  "form_filename1":[<tornado.httputil.HTTPFile>, <tornado.httputil.HTTPFile>], "form_filename2":[<tornado.httputil.HTTPFile>,], ... } 

tornado.httputil.HTTPFile是接收到的文件對象,它有三個屬性:

  • filename 文件的實際名字,與form_filename1不同,字典中的鍵名代表的是表單對應項的名字;
  • body 文件的數據實體;
  • content_type 文件的類型。

注:這三個對象屬性可以像字典一樣支持關鍵字索引,如request.files["form_filename1"][0]["body"]。

保存傳來的文件:

# coding:utf-8
import tornado.web
import tornado.ioloop
import tornado.httpserver
import tornado.options
from tornado.options import options, define
from tornado.web import RequestHandler
 
define("port", default=8000, type=int, help="給個端口號唄")
 
class IndexHandler(RequestHandler):
    def get(self):
        self.write("""<form action='/' enctype="multipart/form-data"  method='post'> 
                    <p> <input type='file' name='img' /></p>
                    <p><input type='submit' /></p>
                    </form>""")     # 表單提交文件的時候要加上這句話enctype="multipart/form-data" 
    def post(self):
        files = self.request.files
        print(files)    # {'img': [{'filename': 'xinge', 'content_type': 'application/octet-stream', 'body': b'abc123'}]}
        img_files = files.get("img")
        print(img_files,'=========================================')    # [{'filename': 'xinge', 'content_type': 'application/octet-stream', 'body': b'abc123'}]
        if img_files:
            img_file = img_files[0]["body"]     # self.request.file['img':文件名][0:取第一個]['body':內容]
            with open("/home/x5456/桌面/xin/image01", 'wb') as f:      # 保存文件到本地
                print(img_file)     # b'abc123' 文件內容
                f.write(img_file)
        self.write("OK")
 
if __name__ == "__main__":
    tornado.options.parse_command_line()
    app = tornado.web.Application([
        (r"/", IndexHandler),
    ])
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.current().start()

保存前端傳來的json/xml數據:

# coding:utf-8
import tornado.web
import tornado.ioloop
import tornado.httpserver
import tornado.options
import json

from tornado.web import url,RequestHandler
from tornado.options import define,options

tornado.options.define("port",default=8000,type=int,help="給個端口號唄")

class IndexHandler(RequestHandler):
    def post(self):
        
        # ====================== 獲取json/xml數據(沒法直接獲取,需要手動獲取)  ======================
        print(self.request.headers.get("Content-Type"))    # 獲取請求數據類型
        json_data = self.request.body       # 獲取請求體
        json_args = json.loads(json_data)   # 將json解碼

        self.write(str(json_args))     # 返回的都是unicode字符串



if __name__ == "__main__":
    tornado.options.parse_command_line()
    app = tornado.web.Application(
        [
        (r"/",IndexHandler),
        ],
        debug = True
    )
    
    http_server = tornado.httpserver.HTTPServer(app)    # 創建httpserver實例
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.current().start()

5. 正則提取uri

tornado中對於路由映射也支持正則提取uri,提取出來的參數會作為RequestHandler中對應請求方式的成員方法參數。若在正則表達式中定義了名字,則參數按名傳遞;若未定義名字,則參數按順序傳遞。提取出來的參數會作為對應請求方式的成員方法的參數。

# coding:utf-8

import tornado.web
import tornado.ioloop
import tornado.httpserver
import tornado.options
from tornado.options import options, define
from tornado.web import RequestHandler

define("port", default=8000, type=int, help="run server on the given port.")

class IndexHandler(RequestHandler):
    def get(self):
        self.write("hello itcast.")

class SubjectCityHandler(RequestHandler):
    def get(self, subject, city):
        self.write(("Subject: %s<br/>City: %s" % (subject, city)))

class SubjectDateHandler(RequestHandler):
    def get(self, date, subject):
        self.write(("Date: %s<br/>Subject: %s" % (date, subject)))

if __name__ == "__main__":
    tornado.options.parse_command_line()
    app = tornado.web.Application([
        (r"/", IndexHandler),
        (r"/sub-city/(.+)/([a-z]+)", SubjectCityHandler), # 無名方式
        (r"/sub-date/(?P<subject>.+)/(?P<date>\d+)", SubjectDateHandler), # 命名方式
    ])
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.current().start()

  


免責聲明!

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



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