preface

这里我主要说说flask的URL玩法

include:

  1. 动态URL规则
  2. 自定义URL转换器
  3. HTTP方法
  4. 唯一的URL
  5. 构造URL
  6. 跳转和重定向

动态URL规则

URL规则可以添加变量部分,也就是服务器同种规则的URL抽象成一个URL模式,如/item/1/,/item/2等等。为了不需要写那么多的url,我们可以是匹配URL,如下所示:

@app.route('/item/<id>/')
def item(id):
return "hi guy,it is {} ".format(id)

尖括号的内容就是动态的。凡事匹配到/item/前缀的URL都会映射到这个路由上,在内部通过id作为参数而获得。

他使用了特殊的字段标记<variable_name>,默认的类型是字符串。如果有需要指定参数类型的,需要标记成converter:variable_name这样的格式,converter有下面几种。

  1. string: 接受没有任何斜杠“/”的的文本,默认就是
  2. int: 接受整形
  3. float:接受浮点型
  4. path:和默认的相似,但也接受斜杠
  5. uuid: 只接受uuid字符串。
  6. any: 可以指定多种路径,但是需要传入参数。
@app.route('/<any(a,b):page_name>/')

访问/a/和访问/b/都符合这个规则,/a/对应的就是page_name就是a。

如果不希望定制子路径,还可以通过传递参数的方式。比如/people/?name=a,/people/?name=b,这样通过name=request.args.get('name') 获得传入name的值。如果是POST的方法,那么表单参数通过requests.form.get('name')获得。

自定义URL转换器

Reddit可以通过在URL中用个加号(+)隔开各个社区的名字,方便同时查看多个社区的帖子。比如访问“http://reddit.com/r/flask+listp” ,就可以同时看flask和lisp两个社区的帖子。我们自定义一个转换器来实现这个功能,它还可以设置所使用的分隔符,不一定使用加号(+)。

代码如下:

# coding:utf-8
import os
import sys
import urllib
from flask import Flask
from werkzeug.routing import BaseConverter path = os.path.dirname( os.path.dirname( __file__ ) )
sys.path.append( path )
app = Flask(__name__) class ListConverter(BaseConverter):
def __init__(self,url_map,separator='+'):
super(ListConverter,self).__init__(url_map) # 重写父类的方法
self.separator = urllib.unquote(separator) def to_python(self, value):
return value.split(self.separator) def to_url(self,values):
return self.separator.join(super(BaseConverter,self).to_url(value) for value in values) app.url_map.converters['list'] = ListConverter @app.route('/list1/<list:page_names>/')
def list1(page_names):
return "Separator: {} {} ".format('+',page_names) @app.route('/list2/<list(separator=u"|"):page_names>/')
def list2(page_names):
return "Separator: {} {} ".format("|",page_names) if __name__ == '__main__':
app.run(host='0.0.0.0',port=9000)

自定义转换器需要继承至BaseConverter,要设置to_python和to_url两个方法

  • to_python: 把路径转为一个Python对象
  • to_url: 把参数转为符合URL的形式。

我们访问两个url就可以看懂啊效果:

  1. http://127.0.0.1:9000/list2/a|b/ =效果是> Separator: | [u'a', u'b']
  2. http://127.0.0.1:9000/list1/a+b/ =效果是> Separator: + [u'a', u'b']

HTTP方法

HTTP 可以访问多个URL方法,默认情况下,路由只回应GET请求,但是通过app.route装饰器传递methods参数可以改变这个行为,如下所示:

@app.route('/item/<id>/',methods=['GET','POST','DELETE'])

methods里面可以写入所有HTTP的方法。

如果存在GET,那么会自动地添加HEAD方法,无须干预,它会确保遵照HTTP RFC(描述HTTP协议的文档)处理HEAD请求,所以完全可以忽略

唯一的URL

Flask的URL规则基于Werkzeug的路由模块,这个模块背后的思想就是基于Apache以及更早的HTTP服务器主张,希望保证优雅且唯一的URL。

举个例子:

@app.route('/project/')
def project():
return 'THe project Page'

上述看起来很像一个文件系统中的文件夹,以访问一个结尾不带斜线的URL会被重定向到带斜线的规范的URL上去,这样有助于避免搜索引擎索引到同一个页面两次。

再看一个例子:

@app.route('/about')
def about():
return "the about apge"

URL结尾不带斜线的,很像文件的路径,但是访问带斜线的URL(/about/)会产生一个“Not Found” 的错误

构造URL

用url_for 构建URL,它接受函数名作为第一个参数,也接受对应的URL规则变量部分命名的参数,未知的变量部分会添加到URL微末作为查询参数。

构建URL而不选择直接在代码中拼URL原因有两点:

  1. 在未来有更改的时候只需要一次性修改URL,而不用到处去替换。
  2. url构建会转义特殊字符和Unicode数据,这些工作不需要我们自己处理。

请看例子:

#coding:utf-8
from flask import Flask,url_for
app = Flask(__name__) @app.route('/item/1/')
def item(id):
print('id',id) with app.test_request_context():
print url_for('item',id='1')
print(url_for('item',id=2,next='/'))

test_request_context可以帮助我们在交互模式下产生请求上下文,我们运行下这个py文件,查看下结果:

/root/venv/bin/python /root/PycharmProjects/FlaskPratice/pratice2.py
/item/1/?id=1
/item/1/?id=2&next=%2F

跳转和重定向

跳转(状态码301)多用于就网址在废弃前装箱新网址,以保证用户的访问,有页面被永久移走的概念。重定向(状态码302)表示页面暂时性的转移。但是也不建议经常性用重定向。在Flask里面是通过flask.rediret实现的,在django里面通过HttpRedirect实现的。

redirect(location)   # 默认是301
redirect(location,code=301) # 通过code参数可以指定状态码

Flask还可以支持303,305,307重定向,但是很少用到。

基于前面所讲的内容,我们来看一个更全面的例子。

config.py和simple.py都在同一个目录下面,

首先看下存放配置的config:

# coding=utf-8
DEBUG = False try:
from local_settings import *
except ImportError:
pass

我们在看看主体py文件的代码

# coding=utf-8
from flask import Flask, request, abort, redirect, url_for app = Flask(__name__)
app.config.from_object('config') @app.route('/people/')
def people():
name = request.args.get('name')
if not name:
return redirect(url_for('login'))
user_agent = request.headers.get('User-Agent')
return 'Name: {0}; UA: {1}'.format(name, user_agent) @app.route('/login/', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
user_id = request.headers.get('user_id')
return 'User: {} login'.format(user_id)
else:
return 'Open Login page' @app.route('/secret/')
def secret():
abort(401)
print 'This is never executed' if __name__ == '__main__':
app.run(host='0.0.0.0', port=80, debug=app.debug)

参数解释下:

  1. 访问/people 的请求访问跳转到/people/,保证URL的唯一性。
  2. reqeusts.headers 存放请求的头信息,通过它可以获取了UA值。
  3. request.method 的值请求的类型。
  4. 执行abort(401)会放弃请求并返回错误代码401,表示访问错误,之后的代码永远不会被执行。
  5. app.debug 就是我们在config.py里面配置的。

2 URL的玩法的更多相关文章

  1. 性能测试脚本新玩法---fiddler&&Jmeter

    飞测说:最近接触移动项目,测试app,需要做移动app的性能测试,想通过代理来录制,但是jmeter的代理录制效果真心不是很好,自己一个个请求来写代码,太浪时间了,那么有没有其他的办法呢? 我们都知道 ...

  2. 关于Console控制台输出的玩法

    你在浏览网页的时候,是否注意过这些网页的控制台输出了什么? Console这种东西,其实一般只有前端工作者才会注意到.console在我们实际开发中可是个宝贝,他是各种error和warning的展示 ...

  3. [深入学习Web安全](11)之XSS玩法

    [深入学习Web安全](11)之XSS玩法 本文转自:i春秋社区 前言这篇paper,我们将学习如何优雅的调戏XSS.我们会教大家一些不常用的,但很实用的XSS姿势.我们在正式进入主题之前,先来说一下 ...

  4. maven 高级玩法

    maven 高级玩法 标签(空格分隔): maven 实用技巧 Maven 提速 多线程 # 用 4 个线程构建,以及根据 CPU 核数每个核分配 1 个线程进行构建 $ mvn -T 4 clean ...

  5. XSS漏洞的渗透利用另类玩法

    XSS漏洞的渗透利用另类玩法 2017-08-08 18:20程序设计/微软/手机 作者:色豹 i春秋社区 今天就来讲一下大家都熟悉的 xss漏洞的渗透利用.相信大家对xss已经很熟悉了,但是很多安全 ...

  6. 接口测试的N中玩法

    在我看来接口测试相对其他类型的测试是比较简单的.对于最常见的HTTP接口,只需要知道接口的 URL.方法.参数类型.返回值 ... 就可以对接口进行测试了. apifox 如果你是入门级选手,那么ap ...

  7. WEB安全新玩法 [1] 业务安全动态加固平台

    近年来,信息安全体系建设趋于完善,以注入攻击.跨站攻击等为代表的传统 Web 应用层攻击很大程度上得到了缓解.但是,Web 应用的业务功能日益丰富.在线交易活动愈加频繁,新的安全问题也随之呈现:基于 ...

  8. [C#] 软硬结合第二篇——酷我音乐盒的逆天玩法

    1.灵感来源: LZ是纯宅男,一天从早上8:00起一直要呆在电脑旁到晚上12:00左右吧~平时也没人来闲聊几句,刷空间暑假也没啥动态,听音乐吧...~有些确实不好听,于是就不得不打断手头的工作去点击下 ...

  9. git分布式版本控制玩法

    git分布式版本控制玩法 Git distributed version control play github的配置安装步骤:1.下载git bash(从http://www.git-scm.com ...

随机推荐

  1. java框架篇---struts之OGNL详解

    OGNL(Object Graph Navigation Language),是一种表达式语言.使用这种表达式语言,你可以通过某种表达式语法,存取Java对象树中的任意属性.调用Java对象树的方法. ...

  2. J.U.C--locks--AQS分析

    看一下AbstractQueuedSynchronizer(下面简称AQS)的子类就行知道,J.U.C中宣传的封装良好的同步工具类Semaphore.CountDownLatch.ReentrantL ...

  3. spark wordcont Spark: sortBy和sortByKey函数详解

    //统计单词top10def main(args: Array[String]): Unit = { val conf = new SparkConf().setAppName("tst&q ...

  4. iPad适合写作吗

    我一直感觉对着电脑不利于思考,当需要纯粹的思考时,我习惯让视线离开屏幕,起身走动两圈,再用纸和笔整理思路,想清楚后,开始动手编码. 双手端着iPad时,似乎也能有类似纸与笔的组合效果,大脑能适应那种界 ...

  5. CPP_运算符重载及友元

    运算符重载 两种重载方法1)成员函数 a + b => a.operator+(b); 一个参数 2)友元函数 a + b => operator+(a, b); 两个参数. friend ...

  6. python -修改文件中某一行

    写代码写错了顺序,所以想办法把x,y坐标调换回来 def change_ptsxy(fileName): fp = open(fileName) i = file_data = "" ...

  7. Iconfont在移动端应用的问题

    关于部分奇葩用户代理不显示字体图标 以酷派为代表的部分安卓手机自带浏览器.微信/QQ WebView 等用户代理无法正常显示 Icon Font,原因可能是这些用户代理无法正确处理伪元素 conten ...

  8. Eclipse调试Java的10个技巧【转】

    clipse调试Java的10个技巧 先提三点 不要使用System.out.println作为调试工具 启用所有组件的详细的日志记录级别 使用一个日志分析器来阅读日志 1.条件断点 想象一下我们平时 ...

  9. 高大上的动态CSS

    项目里要添加 custom css 功能 (dynamic stylesheet ),总结一下实现方法. 1.在JSP中动态设定文件path 预先生成一些css文件,由用户选择,在jsp被请求时,动态 ...

  10. "iostat" On Linux

    CPU是一台电脑的大脑.所有的处理命令都运行在上面.I/O(输入/输出)同样扮演了一个重要角色.硬盘用于提供数据给处理器并保存CPU处理过的数据.一种衡量处理器和I/O利用率的方法是使用iostat命 ...