输出
write方式
前面介绍基本的输出,可以通过write把字符串输出到浏览器,除此之外,write还可以把那些东西输出到浏览器呢?
- 字节bytes
self.write(b'Tornado<br/>') #bytes 字节
- 字典dict
user = {'name':'cainiao','age':18} #字典
self.write(user) #字典
- 字符Unicode
self.write('22<br/>33')
- 其他
li = [1,2,3,4]
import json
li = json.dumps(li) #列表,需要序列化成json字符
self.write(li)
代码实例
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
from tornado.options import define,options
define('port', default=8080, help='run port', type=int)
class TestHandler(tornado.web.RequestHandler):
def get(self):
self.write(b'Tornado<br/>') #bytes 字节
user = {'name':'cainiao','age':18} #字典
print(user)
print(repr(user))
self.write('22<br/>33')
self.write(user) #字典,如果输出有个是字典,那么其他一并当做json格式输出,所以上面那个<br/>会失效显示出来,
li = [1,2,3,4]
import json
li = json.dumps(li) #列表,需要序列化成json字符
print(li)
print(repr(li))
self.write(li)
li = json.loads(li) #反序列
print(li)
print(repr(li))
application = tornado.web.Application(
handlers = [
(r'/test',TestHandler),
],
debug = True #调试模式,修改后自动重启服务,不需要自动重启,生产情况下切勿开启,安全性
)
if __name__ == '__main__':
tornado.options.parse_command_line()
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(options.port)
tornado.ioloop.IOLoop.instance().start()
运行结果:
注意:上面<br/>
标签失效,显示出来了,这是为什么呢?
解答:按照源码write方法解释
意思是如果给定的是字典形式,会将其转化为json格式和设置响应头为
application/json
格式,所以代码中几个write方法中,只有有一个为字典就都会转化!
总结:
1、write可以接受 bytes、unicode字符和字典这个三个对象;
2、如果接受的是字典,会把字典转化成 JSON 字符串,因此write也可以接受 JSON 字符串。所以对于其他的可以先转换成json格式。
缓冲区flush
write 会先把内容放在缓冲区,正常情况下,当请求处理完成后会自动把缓冲区的内容输出到浏览器,但是可以调用 flush 方法,这样可以直接把缓冲区的内容输出到浏览器,不用等待请求处理完成,这就可能先看到flush前面部分内容,后面部分内容等请求处理完才能看到。
代码实例
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
from tornado.options import define,options
define('port', default=8080, help='run port', type=int)
class TestHandler(tornado.web.RequestHandler):
def get(self):
self.write(b'Tornado<br/>') #bytes 字节
user = {'name':'cainiao','age':18} #字典
print(user)
print(repr(user))
self.write('22<br/>33')
self.flush() #这样可以直接把缓冲区的内容输出到浏览器,不用等待请求处理完成,
import time
time.sleep(6) #通过sleep暂停几秒好验证一般write一次性全部刷到客户端去
self.write(user) #字典,如果输出有个是字典,那么其他一并当做json格式输出,所以上面那个<br/>会失效显示出来,
li = [1,2,3,4]
import json
li = json.dumps(li) #列表,需要序列化成json字符
print(li)
print(repr(li))
self.write(li)
li = json.loads(li) #反序列
print(li)
print(repr(li))
application = tornado.web.Application(
handlers = [
(r'/test',TestHandler),
],
debug = True #调试模式,修改后自动重启服务,不需要自动重启,生产情况下切勿开启,安全性
)
if __name__ == '__main__':
tornado.options.parse_command_line()
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(options.port)
tornado.ioloop.IOLoop.instance().start()
运行结果
效果:可以在浏览器看到,刚开始输出flush前面部分,其他部分等请求处理完自动输出到浏览器中,sleep(6)休眠6秒钟主要是为了好验证看出效果。最终显示在浏览器的结果可以看出没有出现刚开始一样的
<br/>
原始标签,而是换行了,这是因为flush前面部分没有字典,所以响应的头部类型Content-Type:text/html;
后面部分就算有字典不会再生成类型,一次请求资源只有一次生成。如果将flush写到输出字典的后面部分
self.write(user)
self.flush()
输出结果:
内容类型就会变成json格式。
render方式,Tornado返回一个html文件
self.render('index.html')
通过render可以返回一个 html 文件,想要 Tornado 能够正确的找到 html 文件,需要在 Application 中指定文件的位置
redirect方式,跳转路由,重定向
self.redirect(r'/index')
通过redirect可以跳转到指定的路由。
以上综合代码:
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
from tornado.options import define,options
define('port', default=8080, help='run port', type=int)
class IndexHandler(tornado.web.RequestHandler):
def get(self):
self.render('index.html') #通过render可以返回一个 html 文件
class HomeHandleer(tornado.web.RequestHandler):
def get(self):
self.redirect(r'/index')
application = tornado.web.Application(
handlers = [
(r'/index',IndexHandler),
(r'/home',HomeHandleer)
],
template_path = 'templates', #想要Tornado能够正确的找到html文件,需要在 Application 中指定文件的位置
debug = True #调试模式,修改后自动重启服务,不需要自动重启,生产情况下切勿开启,安全性
)
if __name__ == '__main__':
tornado.options.parse_command_line()
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(options.port)
tornado.ioloop.IOLoop.instance().start()
返回html文件效果:
重定向效果:
结束请求
一般程序执行完结束,一次请求结束,当调用 finish 之后,请求处理完成,类似于函数中的 return (注意:请求当中不能出现return) ,其后不能再执行 write 、render、redirect,否则会报错。
前端看不出错误,后端报错:
获取请求信息
class IndexHandler(tornado.web.RequestHandler):
def get(self):
self.write(self.request.remote_ip) #客户端ip
self.write(self.request.full_url()) #请求url地址
print(self.request.request_time()) #访问时间
print(self.request.uri) #请求路由
print(self.request.path) #请求路由
#继承类 tornado.web.RequestHandler 之后,可以直接调用 self.request 来获取客户端请求信息
method | HTTP请求方法,例如 GET 或 POST | |
---|---|---|
remote_ip | 客户端的IP地址,返回值类型为字符串 | |
full_url() | 重新构建此请求的完整URL | |
request_time() | 返回此请求执行所花费的时间 | |
uri | 请求的完整uri | |
path | 路径部分的uri | |
query | 查询部分的uri | |
vertion | 请求中指定的HTTP版本,例如“HTTP / 1.1” |
总结:继承类tornado.web.RequestHandler之后,可以直接调用self.request来获取客户端请求信息。
输入
代码实例
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
from tornado.options import define,options
define('port', default=8080, help='run port', type=int)
class RegisterHandler(tornado.web.RequestHandler):
def get(self):
info = self.get_argument('info','')
self.write(info)
self.render('register.html')
def post(self, *args, **kwargs):
name = self.get_argument('name','')
passwd = self.get_argument('password','')
self.write(name)
self.write('name:'+name+'<br/>')
self.write('password:'+passwd)
application = tornado.web.Application(
handlers = [
(r'/register',RegisterHandler),
],
template_path = 'templates', #想要Tornado能够正确的找到html文件,需要在 Application 中指定文件的位置
debug = True #调试模式,修改后自动重启服务,不需要自动重启,生产情况下切勿开启,安全性
)
if __name__ == '__main__':
tornado.options.parse_command_line()
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(options.port)
tornado.ioloop.IOLoop.instance().start()
由以上可以得出
get_argument
get和post都可以获取对应参数。
- 获取url数据,get_argument可以获取 URL (查询字符串)中的参数。
- 获取body数据,get_argument可以获取body(请求体)中的数据。
- get_argument返回的值始终是unicode。
其他输入了解
- self.get_query_argument('name', 'query'),获取查询字符串中参数,即url中的。对应的也有:get_query_arguments。
- self.get_body_argument('name', 'body'),获取 body 中的参数。对应的也有: get_body_arguments。
url传参
查询字符串风格
class RegisterHandler(tornado.web.RequestHandler):
def get(self):
info = self.get_argument('info','')
self.write(info)
路由
(r'/register',RegisterHandler)
URL
http://127.0.0.1:8000/register?info=please login at first
REST风格
handler
class LoginHandler(tornado.web.RequestHandler):
def get(self, name, age):
self.write('name:%s<br/>age:%s'%(name,age))
路由
(r'/login/(.+)/([0-9]+)',LoginHandler), #正则写法,使用圆括号进行传参的时候是位置传参
(r'/login/(?P<name>.+)/(?P<age>[0-9]+)',LoginHandler) #命名组写法,使用关键字,路由与handler方法不一定顺序一致