一、代码目录构建

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. Java中的split函数的用法

    Java中的 split  函数是用于按指定字符(串)或正则去分割某个字符串,结果以字符串数组形式返回: 例如: String str="1234@abc"; String[] a ...

  2. java严格验证日期是否正确的代码

    package com.xxxx.util; /** * 输入日期 并进行验证格式是否正确 */ public class FDate { public static void main(String ...

  3. NFS详细分析

    1. NFS服务介绍 1.1什么是NFS服务 NFS(Network File System)即网络文件系统,它允许网络中的计算机之间通过TCP/IP网络共享资源.在NFS的应用中,本地NFS的客户端 ...

  4. centos中git使用

    先用root用户登录, yum install git 进行安装,然后退出用普通用户登录. ssh-keygen -t rsa -C "tuhooo@163.com" 登录GitH ...

  5. Hibernate: 数据持久层框架

    Hibernate 是一种Java语言下的对象关系映射解决方案. 它是使用GNU宽通用公共许可证发行的自由.开源的软件.它为面向对象的领域模型到传统的关系型数据库的映射,提供了一个使用方便的框架.Hi ...

  6. android 小游戏之数字猜猜

    http://www.cnblogs.com/whatbeg/p/4152333.html

  7. 关于reset.css的那些事

    分析过程:body: 发现在没有填写任何内容的情况下是没有margin 的  只有在加入了文字或者div中以后才有了margin(废话)那么 我想问一下 body的padding 默认的有吗??在哪里 ...

  8. web安全之SQL注入---第二章 什么是sql注入?

    如何理解SQL注入?SQL注入是一种将SQL代码添加到输入参数中传递到SQL服务器解析并执行的一种攻击方法总结:其实就是输入的参数没有进行过滤,直接参加sql语句的运算,达到不可预想的结果.SQL注入 ...

  9. BZOJ 1602 [Usaco2008 Oct]牧场行走 dfs

    题意:id=1602">链接 方法:深搜暴力 解析: 这题刚看完还有点意思,没看范围前想了想树形DP,只是随便画个图看出来是没法DP的,所以去看范围. woc我没看错范围?果断n^2暴 ...

  10. Android Studio 中 Gradle 依赖的统一管理(rootProjectt)

    最近遇到Android Studio 中 Gradle 依赖的统一管理的不懂得地方,看大神的也没看懂,百度了一下,使用起来还挺方便 下面是链接,在这里我就不详细说明了, http://www.jian ...