一、代码目录构建

controllers  :处理业务逻辑的

account:处理账户相关的

上面目录作用和内容

controllers 包 :处理业务逻辑的

account:处理账户相关的

home是主页内容文件

settings   包:内容设置等

Setting:配置文件

statics    包: 静态文件的下相关目录

views     包: HTML文件包

内容分别为:

#/usr/bin/env python
#-*-coding:utf- -*-
import tornado.web class LoginHandler(tornado.web.RequestHandler):
def get(self,*args,**kwargs):
self.write("ok")
class LogoutHandler(tornado.web.RequestHandler):
def get(self, *args, **kwargs):
self.write("ok")
class RegisterHandler(tornado.web.RedirectHandler):
def get(self,*args,**kwargs):
self.write("ok")

account文件

#/usr/bin/env python
#-*-coding:utf--*-
import tornado.web class IndexHandler(tornado.web.RequestHandler):
def get(self, *args, **kwargs):
# self.write("index.html")
self.render("index.html")

home文件

#/usr/bin/env python
#-*-coding:utf--*- settings={
"template_path":"views",#模板路径的配置
"static_path":"statics" #静态文件
}

Setting文件

#/bin/usr/env python
#-*- coding:utf- -*-
import tornado.ioloop
import tornado.web
from controllers import home
from settings import Setting #路由映射,路由系统
application=tornado.web.Application(
[(r"/index",home.IndexHandler),],
**Setting.settings
) if __name__=="__main__":
application.listen()
tornado.ioloop.IOLoop.instance().start()

start文件

其实就是把tornado拆解了

#!/usr/bin/env python
# -*- coding:utf- -*- # 首先导入模块
import tornado.ioloop
import tornado.web
# 让这个类继承 执行
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.render("s1.html")
# 路由映射,也可以叫做路由系统
application = tornado.web.Application([
(r"/index", MainHandler),
])
if __name__ == "__main__":
application.listen()
tornado.ioloop.IOLoop.instance().start()

二、基于正则的动态路由

设置分页:在路由系统中,用正则匹配数字,并且让第一个明明为num,第二个为nid

#路由映射,路由系统
application=tornado.web.Application(
[(r"/index/(?P<num>\d*)/(?P<nid>\d*)",home.IndexHandler),],
**Setting.settings
)
#/usr/bin/env python
#-*-coding:utf--*-
import tornado.web class IndexHandler(tornado.web.RequestHandler):
def get(self,nid,num):
# self.write("index.html")
print(nid,num)
self.render("index.html")

在home文件中设置

在网页url中输入http://127.0.0.1:8000/index/12321/151

在后台中输出 151 和12321

三、路由系统之二级域名

application.add_handlers("www.cnblogs.com",[
(r"/index/(?P<page>\d*)",这里是自己定义的类)
])

二级路由就是:首先匹配域名,然后再匹配域名下的各个页面

一级路由是直接匹配各个页面

四、自定义分页:

redirect_to实现的是action方法的跳转,向浏览器发起一个新的请求,具体使用方法如下

注意点:用户连接tornado的时候,这个框架会用get方法给服务端发送页面信息,然后客户端向服务端发送消息,这里是用post方式,从客户端发送消息到服务端
#/bin/usr/env python
#-*- coding:utf- -*-
import tornado.ioloop
import tornado.web
from controllers import home
from settings import Setting #路由映射,路由系统
application=tornado.web.Application(
[(r"/index/(?P<page>\d*)",home.IndexHandler),],
**Setting.settings
) if __name__=="__main__":
application.listen()
tornado.ioloop.IOLoop.instance().start()

start代码

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<h1>提交数据</h1>
<form method="post" action="/index/1">
<input name="username" type="text"/>
<input name="email" type="text"/>
<input type="submit" value="提交"/>
</form>
<h1>显示数据</h1>
<table border="">
<thead>
<tr>
<th>用户名</th>
<th>邮箱</th>
</tr>
</thead>
<tbody>
{% for line in list_info %}
<tr>
<td>{{line['username']}}</td>
<td>{{line['email']}}</td>
</tr>
{% end %}
</tbody>
</table>
</body>
</html>

HTML代码

#/usr/bin/env python
#-*-coding:utf--*-
import tornado.web LIST_INFO=[
{"username":"aa","email":"pyrene3110436742@162.com"}
]
class IndexHandler(tornado.web.RequestHandler):
def get(self,page):
#假如每页显示5条数据
# page是当前页
# 第一页:: LIST_INFO[:]
#第二页:: LIST_INFO[:]
try:
page=int(page)
except Exception:
page=
if page<:
page=
start=(page-)*
end=page*
current_list=LIST_INFO[start:end] # print(nid,num)
self.render("home/index.html" ,list_info=current_list)
def post(self, *args, **kwargs):
user=self.get_argument("username")
email=self.get_argument("email")
temp={"username":user,"email":email}
LIST_INFO.append(temp)
self.redirect("/index/1")

home代码

分析:

这里有两种内容

1、用户通过表格form提交数据,通过post方法,把输入的内容添加到LIST_INFO列表中,并且通过redirect方法跳转到get方法中返回给客户端

2、内部做了页面判断,并且让页面只显示5条数据,用户通过路由系统输入url来访问每一页

自定义分页优化

通过传值来记住当前页

三中的bug问题点在于:页面输入的时候,会跳转到首页,要解决

#/usr/bin/env python
#-*-coding:utf--*-
import tornado.web LIST_INFO=[
{"username":"aa","email":"pyrene3110436742@162.com"}
]
class IndexHandler(tornado.web.RequestHandler):
def get(self,page):
#假如每页显示5条数据
# page是当前页
# 第一页:: LIST_INFO[:]
#第二页:: LIST_INFO[:]
try:
page=int(page)
except Exception:
page=
if page<:
page=
start=(page-)*
end=page*
current_list=LIST_INFO[start:end] # print(nid,num)
self.render("home/index.html" ,list_info=current_list,current_page=page)
def post(self,page):
user=self.get_argument("username")
email=self.get_argument("email")
temp={"username":user,"email":email}
LIST_INFO.append(temp)
self.redirect("/index/"+page)

home代码:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<h1>提交数据</h1>
<form method="post" action="/index/{{current_page}}">
<input name="username" type="text"/>
<input name="email" type="text"/>
<input type="submit" value="提交"/>
</form>
<h1>显示数据</h1>
<table border="">
<thead>
<tr>
<th>用户名</th>
<th>邮箱</th>
</tr>
</thead>
<tbody>
{% for line in list_info %}
<tr>
<td>{{line['username']}}</td>
<td>{{line['email']}}</td>
</tr>
{% end %}
</tbody>
</table>
</body>
</html>

index代码

后台get方法中自定义页码变量,传入到html中,之后用户输入触发post方法,然后在post方法中跳转到当前页面

自定义分页二:实现下图中的分页

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>
.pager a{
display: inline-block;
padding: 5px;
margin: 3px;
background-color: cadetblue;
}
.pager a.active{
background-color:brown ;
color: white;
}
</style>
</head>
<body>
<h1>提交数据</h1>
<form method="post" action="/index/{{current_page}}">
<input name="username" type="text"/>
<input name="email" type="text"/>
<input type="submit" value="提交"/>
</form>
<h1>显示数据</h1>
<table border="">
<thead>
<tr>
<th>用户名</th>
<th>邮箱</th>
</tr>
</thead>
<tbody>
{% for line in list_info %}
<tr>
<!--<td>{{line['username']}}</td>-->
<td>{% raw line['username']%}</td>
<td>{{line['email']}}</td>
</tr>
{% end %}
</tbody>
</table>
<div class="pager">
{% raw str_page %}
</div>
</body>
</html>

HTML代码

#/usr/bin/env python
#-*-coding:utf--*-
import tornado.web LIST_INFO=[
{"username":"aa","email":"pyrene3110436742@162.com"}
]
for i in range():
temp={"username":"bb"+str(i),"email":str(i)+""}
LIST_INFO.append(temp)
class IndexHandler(tornado.web.RequestHandler):
def get(self,page):
#假如每页显示5条数据
# page是当前页
# 第一页:: LIST_INFO[:]
#第二页:: LIST_INFO[:]
try:
page=int(page)
except Exception:
page=
if page<:
page=
start=(page-)*
end=page*
current_list=LIST_INFO[start:end] all_pager,c=divmod(len(LIST_INFO),)
if c>:
all_pager+= list_page=[] for p in range(all_pager):
# 设置当前页的样式
if p+ ==page:
temp='<a class="active" href="/index/%s">%s</a>' %(p+,p+)
else:
temp='<a href="/index/%s">%s</a>'%(p+,p+)
list_page.append(temp) str_page="".join(list_page) # print(nid,num)
self.render("home/index.html" ,list_info=current_list,current_page=page,str_page=str_page)

python代码

 实现步骤:
首先在后台计算出数据的总页数,用divemode的方法
all_pager,c=divmod(len(LIST_INFO),)
if c>:
all_pager+=
all_pager为整数,c为小数,这里判断,如果c为小数的时候让整数加上1,也就是需要显示的页数
、创建一个空列表,并且遍历计算出来的页数,返回给前端页面
list_page=[] for p in range(all_pager):
# 设置当前页的样式
if p+ ==page:
temp='<a class="active" href="/index/%s">%s</a>' %(p+,p+)
else:
temp='<a href="/index/%s">%s</a>'%(p+,p+)
list_page.append(temp) str_page="".join(list_page) # print(nid,num)
self.render("home/index.html" ,list_info=current_list,current_page=page,str_page=str_page)
注意点:
、这里要设置点击到那一页的时候就显示那一页的样式,用于区分
、由于要传给前台的是字符串,所以这里要用join方法分割成字符串
、pag参数为当前页码 前台代码:
<div class="pager">
{% raw str_page %}
</div>
由于后台传过来的数据,要按照后台的样式展示给用户,所以这里要用原声的js显示
这里注意,后台要显示的原生的js必须是指定范围的,不然会被攻击

自定义分页优化

优化如下:

具体思想如下:

all_pager:总页数
current_pager:当前页
# range(当前页-,当前页++)
当 总页数<11的时候
、 显示总页数
当 总页数>11的时候
如果当前页<=:
显示前11页
如果当前页>:
如果:当前页+ >总页数:
总页数 - , 总页数
else:
当前页-, 当前页+
#s t 分页逻辑,这里让其显示11条信息
if all_pager<:
s=
t=all_pager
else:
if page<=:
s=
t=
else:
if(page+)>all_pager:
s=all_pager-
t=all_pager
else:
s=page-
t=page+ #注意这里的p代表的是s和t+1之间的页码
for p in range(s,t+):
# 设置当前页的样式
if p ==page:
temp='<a class="active" href="/index/%s">%s</a>' %(p,p)
else:
temp='<a href="/index/%s">%s</a>'%(p,p)
list_page.append(temp) str_page="".join(list_page)

python代码实现

如何做成插件?

把各个方法分别封装到类中,然后如果以后想用这个插件,直接导入这个插件中的类就可以

如果要封装页码:需要思考需求和产出什么
需求:总页数、当前页
产出:start end str_page 把方法封装到类中,类中分别对应方法
#/usr/bin/env python
#-*-coding:utf--*-
import tornado.web LIST_INFO=[
{"username":"aa","email":"pyrene3110436742@162.com"}
]
for i in range():
temp={"username":"bb"+str(i),"email":str(i)+""}
LIST_INFO.append(temp) class Pagination:
#下面封装的参数分别为,当前页数,和总的数据
def __init__(self,current_page,all_item): #初始化当前页和总页数
all_pager,c=divmod(all_item,) #all_pager为计算的到的总页数,要经过下面的判断
if c>:
all_pager+=
self.all_pager=all_pager try: #为当前页处理异常
current_page=int(current_page)
except Exception:
current_page=
if current_page<:
current_page=
self.current_page=current_page # 加上这样的装饰器,会使下面调用这个方法的时候以访问字段的形式来访问,也就是不用加上括号
@property
def start(self): #当前页的起始数据
return (self.current_page-)*
@property
def end(self): #当前页的结尾数据
return self.current_page* def page_str(self,base_url): # 生成页码逻辑
list_page=[]
if self.all_pager<:
s=
t=self.all_pager
else:
if self.current_page<=:
s=
t=
else:
if( self.current_page+)>self.all_pager:
s=self. current_page-
t=self. current_page
else:
s= self.current_page-
t= self.current_page+
for p in range(s,t+):
if p == self.current_page:
temp='<a class="active" href="%s%s">%s</a>' %(base_url,p,p) #这里设置自定义url
else:
temp='<a href="%s%s">%s</a>'%(base_url,p,p)
list_page.append(temp) return "".join(list_page) #直接返回值 class IndexHandler(tornado.web.RequestHandler):
def get(self,page): page_obj=Pagination(page,len(LIST_INFO)) #传入当前页和总页数生成对象
current_list=LIST_INFO[page_obj.start:page_obj.end] #以字段的方式来应用类中的方法
str_page=page_obj.page_str("/index/") #传入自己自定义的url # 传入参数,当前页的参数和页码数的参数
self.render("home/index.html" ,list_info=current_list,current_page=page_obj.current_page,str_page=str_page) def post(self,page):
user=self.get_argument("username")
email=self.get_argument("email")
temp={"username":user,"email":email}
LIST_INFO.append(temp)
self.redirect("/index/"+page)

python代码

跳转页面

 location.href=”url”
首页:尾页:上一页:下一页都不难 搜索跳转的代码形式:
只要执行上面的就会自动跳转到指定的url
所以这里用了js的事件方法,只不过把js变成字符串的形式传递给前台,然后转化为js代码的形式
#首页
first_page='<a href="%s1">首页</a>'%(base_url,)
list_page.append(first_page) #上一页 current_page- 在javascript中加上javascript:void()表示什么也不做
if self.current_page==:
pre_page='<a href="javascript:void(0)">上一页</a>'
else:
pre_page='<a href="%s%s">上一页</a>'%(base_url,self.current_page-)
list_page.append(pre_page) #中间页数
for p in range(s,t+):
if p == self.current_page:
temp='<a class="active" href="%s%s">%s</a>' %(base_url,p,p) #这里设置自定义url
else:
temp='<a class-"active" href="%s%s">%s</a>'%(base_url,p,p)
list_page.append(temp)
#尾页
last_page='<a href=%s%s>尾页</a>'%(base_url,self.all_pager)
list_page.append(last_page) #下一页 current_page+ 在javascript中加上javascript:void()表示什么也不做
if self.current_page>=self.all_pager:
next_page='<a href="javascript:void(0)">下一页</a>'
else:
next_page='<a href="%s%s">下一页</a>'%(base_url,self.current_page+)
list_page.append(next_page) #跳转页面
jump='''<input type="text" /><a onclick="jump('%s',this);">GO</a>'''%(base_url,)
script='''<script>
function jump(baseUrl,ths){
var val=ths.previousElementSibling.value;
if(val.trim().length>){
location.href=baseUrl+val
}
}
</script>'''
list_page.append(jump)
list_page.append(script)
return "".join(list_page)

五、安全XSS攻击

xss跨站脚本攻击

 <h1>显示数据</h1>
<table border="">
<thead>
<tr>
<th>用户名</th>
<th>邮箱</th>
</tr>
</thead>
<tbody>
{% for line in list_info %}
<tr>
<!--<td>{{line['username']}}</td>-->
<td>{% raw line['username']%}</td>
<td>{{line['email']}}</td>
</tr>
{% end %}
</tbody>
</table>

上面13行的就是以原始方式展示,没做处理,那么无论用户还是后台输入的js代码都会以js形式展示给用户

这种就是xss跨站脚本攻击模式

web框架详解之tornado 三 url和分页的更多相关文章

  1. web框架详解之tornado 一 模板语言以及框架本质

    一.概要 Tornado 是 FriendFeed 使用的可扩展的非阻塞式 web 服务器及其相关工具的开源版本.这个 Web 框架看起来有些像web.py 或者 Google 的 webapp,不过 ...

  2. web框架详解之 tornado 四 模板引擎、session、验证码、xss

    一.模板引擎 基本使用 继承,extends 页面整体布局用继承 导入,include 如果是小组件等重复的那么就用导入 下面是目录 首先在controllers里面创建一个文件,文件里面是页面类 # ...

  3. web框架详解之tornado 二 cookie

    一.tornado之cookie一 目录: <!DOCTYPE html> <html lang="en"> <head> <meta c ...

  4. Spark2.1.0——内置Web框架详解

    Spark2.1.0——内置Web框架详解 任何系统都需要提供监控功能,否则在运行期间发生一些异常时,我们将会束手无策.也许有人说,可以增加日志来解决这个问题.日志只能解决你的程序逻辑在运行期的监控, ...

  5. web框架详解之三Modal

    一.Modal操作之创建表,添加数据 1. 配置Django中settings的设置连接mysql数据库,然后在mysql数据库中创建库 2. 在models中创建表.继承Model 3. 在sett ...

  6. (转) shiro权限框架详解06-shiro与web项目整合(上)

    http://blog.csdn.net/facekbook/article/details/54947730 shiro和web项目整合,实现类似真实项目的应用 本文中使用的项目架构是springM ...

  7. JAVA Eclipse使用Maven构建web项目详解(SSM框架)

    tips: 启动项目后,welcome-file的链接即为测试用例 部署maven web项目 Eclipse使用Maven构建web项目详解 pom.xml添加webapp依赖: <depen ...

  8. jQuery Validate验证框架详解

    转自:http://www.cnblogs.com/linjiqin/p/3431835.html jQuery校验官网地址:http://bassistance.de/jquery-plugins/ ...

  9. 【转】jQuery Validate验证框架详解

    jQuery校验官网地址:http://bassistance.de/jquery-plugins/jquery-plugin-validation 一.导入js库 <script type=& ...

随机推荐

  1. devpress grid表格自适应列宽的问题

    /// <summary> /// 自适应列宽,显示横向滚轴,只有当所有列都已经在界面上加载完成之后才能生效 /// </summary> public void setAut ...

  2. linux watch命令

    watch是一个非常实用的命令,基本所有的Linux发行版都带有这个小工具,如同名字一样,watch可以帮你监测一个命令的运行结果,省得你一遍遍的手动运行.在Linux下,watch是周期性的执行下个 ...

  3. $.ajax 温故而知新坑

    $.ajax的配置项中使用 contentType: "application/json" 时,Data选项允许为String类型,如JSON.stringify({abc:123 ...

  4. tomcat启动之后报404

    启动之后什么异常都没有,但是就报404,很伤,为此和女朋友分了手. 如果项目以前还是可以正常运行的话,不妨试下下面这个办法: 停止tomcat,把tomcat下面的项目删除掉,之后右键单击项目,run ...

  5. 使用React的static方法实现同构以及同构的常见问题

    代码地址请在github查看,假设有新内容.我会定时更新.也欢迎您star,issue,共同进步 1.我们服务端渲染数据从何而来 1.1 怎样写出同构的组件 服务端生成HTML结构有时候并不完好.有时 ...

  6. flume-ng tmp

    flume-ng 是一个分布式,高可用的日志收集系统.主要用来将分布在不同服务器上的业务日志汇总在一个集中的数据存储中心 一 安装与环境配置 下载地址 http://flume.apache.org/ ...

  7. iOS GCD倒计时

    GCD倒计时的好处在于不用考虑是否定时器无法释放的问题,runloop的问题,还有精度更加高 使用GCD创建定时器方法 -(void)startCountDown:(NSInteger)maxTime ...

  8. C++11并发学习之三:线程同步(转载)

    C++11并发学习之三:线程同步 1.<mutex> 头文件介绍 Mutex又称互斥量,C++ 11中与 Mutex 相关的类(包括锁类型)和函数都声明在 <mutex> 头文 ...

  9. Vue实现组件props双向绑定解决方案

    注意: 子组件不能直接修改prop过来的数据,会报错 方案一: 用data对象中创建一个props属性的副本 watch props属性 赋予data副本 来同步组件外对props的修改 watch ...

  10. solr查询

    1.根据字段查询: http://www.360doc.com/content/14/0306/18/203871_358295621.shtml 2.模糊查询: http://www.tuicool ...