天天看点

tornado完成一个简单的登录界面/图片的上传

# 对程序中可能经常变化的值应该提取到配置文件中
# 创建文件夹在文件夹下创建file,充当配置文件
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop
from tornado.options import define, parse_config_file, options
from tornado.web import Application, RequestHandler


class IndexHandler(RequestHandler):
    def get(self,*args,**kwargs):
        html =  '<form method=post action=/login enctype=multipart/form-data>' \
                '<span style=color:red;>用户名</span>'\
                '<input type=text name=username><br>'\
                '<span>密码</span>'\
                '<input type=password name=password><br>'\
                '<input type=file name=avatar><br>'\
                '<input type=file name=avatar><br>'\
                '<input type=submit value=提交>&nbsp;&nbsp;&nbsp'\
                '<input type=reset value=重置>'\
                '</form>'
        fail_html = '<form method=post action=/login>' \
                '<span style=color:red;>用户名</span>'\
                '<input type=text name=username><br>'\
                '<span>密码</span>'\
                '<input type=password name=password><br>'\
                '<span>用户名或密码错误!</span><br>'\
                '<input type=submit value=提交>&nbsp;&nbsp;&nbsp'\
                '<input type=reset value=重置>'\
                '</form>'

        # 获取以get方式发起请求时携带的参数
        msg = self.get_query_argument('msg',None)
        print(msg)# fail
        msgs = self.get_query_arguments('msg')
        print(msgs)# ['fail']
        if msg:
            # msg存在说明出错了
            self.write(fail_html)
        else:
            self.write(html)
    def post(self,*args,**kwargs):
        pass

class LoginHandler(RequestHandler):
    def get(self,*args,**kwargs):
        pass
    def post(self,*args,**kwargs):
        # 如果用户输入的用户名是abc,密码是123
        # 信息输入正确,否则不正确
        username = self.get_body_argument('username',None)
        password = self.get_body_argument('password',None)
        print(username,password)

        usernames = self.get_body_arguments('username')
        passwords = self.get_body_arguments('password')
        print(usernames,passwords)

        if username == 'abc' and password == '123':

            # 如果用户上传了图片,则保存图片
            # self.get_body_argument('avatar')
            # HTTPServerRequest对象的files属性
            # 以字典的方式组织上传的文件
            # 如果图片未上传,则files属性就是一个{}
            files = self.request.files
            if files:
                # 用户上传了文件
                # {键名:[上传文件1,上传文件2...],
                # 键名2:[上传文件a,上传文件b...]}
                # 获取用户上传的图片并保存
                avatars = files.get('avatar')
                for avatar in avatars:
                    # 上传文件有3个属性
                    # type属性:该文件的类型
                    # 例如image/jpeg
                    # filename属性:该文件原始的名字
                    # body属性:该文件的内容(以二进制格式)
                    body = avatar.get('body')
                    # 将body写入一个文件保存起来
                    writer = open('../upload/%s' % avatar.get('filename'),'wb')
                    writer.write(body)
                    writer.close()






            # 跳转到全新的界面
            self.redirect('/blog?username='+username)
        else:
            # 回到登录界面重新登录
            self.redirect('/?msg=fail')

class BlogHandler(RequestHandler):
    def get(self,*args,**kwargs):
        username = self.get_query_argument('username',None)

        # 获取自定义请求头的内容
        print(self.request)
        #  获取所有请求头的相关内容(对象的属性)
        hs = self.request.headers
        # 有这个键就取相关的值,没有这个键就默认为None
        v = hs.get('myhead',None)
        print(v)


        if username:
            self.write('欢迎'+username+'来到BLOG页面')
        else:
            # 没有用户名登录,直接访问了
            self.write('欢迎来到BLOG页面')

    def post(self,*args,**kwargs):
        u = self.get_argument('username')
        print(u)
        us = self.get_arguments('username')
        print(us)


define('duankou',type=int,default=9999)
# 当前文件所在文件夹的上一个(mytornado)下的config/config
parse_config_file('../config/config')


app = Application([('/',IndexHandler),
                   ('/login',LoginHandler),
                   ('/blog',BlogHandler)])
# 创建真正的服务器程序
server = HTTPServer(app)
# 让服务器监听某一个端口(端口号是一个int,原则上不小于10000)
server.listen(options.duankou)
# 当前线程中启动服务器
IOLoop.current().start()
           

相关笔记:

1.利用get_body_argument或get_body_arguments可以获得请求体中的参数.

get_body_argument获得的是单独的参数值,

get_body_arguments获得的是列表形式的参数值.

另外,两者还有2个明显的区别:

1.使用get_body_argument时,最好提供默认值,

防止访问时没有提供服务器需要的参数导致的400:bad request.

使用get_body_arguments时,如果客户端没有提供服务器需要的参数,

只会获得一个空列表,不会产生错误.

2.如果在请求体中存在重名的参数,get_body_argument仅能取到最后一个设置的参数值,

而get_body_arguments可以取到所有的重名的键所对应的值.

例如:对username重复输入zhangsan,lisi,wangwu

get_body_argument取到的值是wangwu

get_body_arguments取到的值是[‘zhangsan’,’lisi’,’wangwu’]

2.界面的跳转:self.redirect(路径)

3.利用get_query_argument或get_query_arguments可以获得以get方式发起请求时携带的参数.

get_query_argument获得的是单独参数值,

get_query_arguments获得的是以列表形式组织的参数值.

另外,两者还有2个明显区别:

1.利用get_query_argument时,最好提供默认值,

防止客户端访问时未提供所需参数导致400:Bad Request错误.

使用get_query_arguments时,客户端未提供所需参数时,只会获得一个空列表,但不会产生错误.

2.当有多个重名的参数提供时,利用get_query_argument仅能获得最后一个参数值,

利用get_query_arguments可以获得所有重名参数的参数值.

4.get_argument获取请求参数:

就像get_query_argument+get_body_argument,

无论请求参数是出现在请求行中还是请求体中,只要有该参数名称就能获得参数值

get_arguments获取请求参数:

就像get_query_arguments+get_body_arguments,

无论请求参数出现在请求行还是请求体中,都能以列表的形式将参数值获得

10.RequestHandler里面有一个属性,叫做request,

引用着一个HttpServerRequest类型的对象,该对象中封装了与请求相关的几乎一切内容.

HTTPServerRequest(protocol=’http’, host=’localhost:9999’, method=’GET’,

uri=’/blog?username=abc’, version=’HTTP/1.1’, remote_ip=’127.0.0.1’,

headers={‘Accept’: ‘text/html,application/xhtml+xml,application/xml;

q=0.9,/;q=0.8’, ‘Host’: ‘localhost:9999’,

‘Accept-Language’: ‘en-GB,en;q=0.5’,

‘Accept-Encoding’: ‘gzip, deflate’,

‘Referer’: ‘http://localhost:9999/‘,

‘Cookie’: ‘csrftoken=ZEOtPCrQtomQLum02c4uZc1LBGZSC1FdHGq1XzwS6TwlQyuHdpl1NaK62VV9IpiK’, ‘Upgrade-Insecure-Requests’: ‘1’, ‘Connection’: ‘keep-alive’, ‘User-Agent’: ‘Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:61.0) Gecko/20100101 Firefox/61.0’})

我们可以利用self.request.headers获取所有请求头.

headers是以字典的方式组织请求头中的名和值.

可以利用self.request.files获取上传的文件.

files也是以字典的形式组织上传的文件.

每一个上传文件都有3个属性:

type属性,表示文件的类型(例如image/jpeg),

filename属性,表示文件的文件名称,

body属性,二进制格式的文件内容.通过标准的IO操作,就可以将上传的文件保存到服务器了.

继续阅读