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()

  

posted @ 2018-01-03 23:09  想54256  阅读(10695)  评论(0编辑  收藏  举报