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. 负数在计算机中的表示 Byte-128

    本文转载: http://blog.csdn.net/njuitjf/article/details/4585247 原码:将一个整数,转换成二进制,就是其原码.如单字节的5的原码为:0000 010 ...

  2. linux用户和权限详解

    1.用户组说明 在使用useradd命令创建用户的时侯可以用-g 和-G 指定用户所属组和附属组.基本组:如果没有指定用户组,创建用户的时候系统会默认同时创建一个和这个用户名同名的组,这个组就是基本组 ...

  3. oracle快速创建可用用户

    执行语句 create user utaptest identified by utaptest; create tablespace utaptestspace datafile 'd:\data. ...

  4. CENTOS6.5安装CDH5.12.1(一) https://mp.weixin.qq.com/s/AP_m0QqKgzEUfjf0PQCX-w

    CENTOS6.5安装CDH5.12.1(一) 原创: Fayson Hadoop实操 2017-09-13 温馨提示:要看高清无码套图,请使用手机打开并单击图片放大查看. 1.概述   本文档主要描 ...

  5. Spring Cloud Config 服务端与 客户端之间的关系

    1.服务端有两个可配置项 # 是否在服务器端进行解密操作,默认开启. # 如果改为不在服务器端开启(false) # 那么一定要将encrypt.key 删除. # 否则会出现客户端无法解密. # 为 ...

  6. fresco中设置占位/加载失败的图片 无效

    在xml中设置  placeholderImage  属性无效.代码如下: <com.facebook.drawee.view.SimpleDraweeView android:id=" ...

  7. ASP.NET中使用JavaScript实现图片自动水平滚动效果

    参照网上的资料,在ASP.NET中使用JavaScript实现图片自动水平滚动效果. 1.页面前台代码: <%@ Page Language="C#" AutoEventWi ...

  8. android AlertDialog.Builder

    AlertDialog的构造方法全部是Protected的,所以不能直接通过new一个AlertDialog来创建出一个AlertDialog. 要创建一个AlertDialog,就要用到AlertD ...

  9. PoseNet: A Convolutional Network for Real-Time 6-DOF Camera Relocalization

    用卷积神经网络对相机位置和角度进行回归.

  10. Android ListView实现单击item出现删除按钮以及滑动出现删除按钮

    我自己一个人弄的公司的产品客户端,所以还是想记录下来以免忘记或者丢失... 在我的上一篇博文(点击打开链接)是一个文件管理的东西,基础组件也是ListView所以在此只是改动一下而已. 单击: 点击出 ...