本文最后更新于:星期二, 六月 16日 2020, 2:36 下午
要学一学Python的后端框架了,只会php不是个事
0x00 前言
前几天打广东省qwb线下赛的时候,运维的web2就是一个Flask框架的博客,结果我对这个web框架一点了解都没有,语法看不懂,路由也看不懂,结果直接导致这道题白给,被删了站都不想恢复。(后来队友@kk跟我说,这题你只要进了后台就有一个flag怼到你脸上…)感觉这不是个事,还是得把各种主力框架的后台都熟悉一下,要不作为一个web手也太不合格了
0x01 安装Flask
Flask可以说是一个轻型的web框架,相比于传统的apache+php,ngnix+php这些框架,Flask使用python作为主语言,虽然现在并不属于主流,但是相对来说用flask作为框架的网站也慢慢多了起来。
先根据官方文档,在本地搭建一个虚拟环境作为测试的环境,官方对python的版本要求如下:
Python 版本
我们推荐使用最新版本的 Python 3 。 Flask 支持 Python 3.4 及更高版本的 Python 3 、 Python 2.7 和 PyPy 。
在本地新建了一个文件夹执行以下命令(我的测试环境是本地的 Ubuntu WSL,python版本是3.5)
mkdir myproject
cd myporject
python3 -m venv venv
显示我缺少 python3-venv
,apt装一下(建议使用清华的apt源)
创建完成之后,目录下会出现一个venv文件夹
激活相应的虚拟环境
. venv/bin/activate
激活之后终端上会显示虚拟环境的名称
然后就可以开始安装Flask了
pip install Flask
0x02 上手
接下来分析一个简单的app
# hello.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, World!'
- 首先
app = Flask(__name__)
是必须的,这样Flask才能找到模板和静态文件 @app.route('/')
则告诉了Flask应用如何进行路由处理,即告诉Flask触发函数的URL- 函数名称被用于生成相关联的URL,返回值则是显示在页面上的信息
运行应用之前,要先导入环境变量:
export FLASK_APP=hello.py
flask run
界面运行效果如下:
外部可见的服务器
运行服务器后,会发现只有你自己的电脑可以使用服务,而网络中的其他电脑却 不行。缺省设置就是这样的,因为在调试模式下该应用的用户可以执行你电脑中 的任意 Python 代码。
如果你关闭了调试器或信任你网络中的用户,那么可以让服务器被公开访问。 只要在命令行上简单的加上
--host=0.0.0.0
即可:$ flask run --host=0.0.0.0
这行代码告诉你的操作系统监听所有公开的 IP 。
调试模式
Flask还有一个很实用的调试模式,这在我们测试和编写应用的时候挺实用的,开启调试模式之后,我们每次更改代码它都会自动重载,不需要我们手动反复开启服务了,而且在代码出错时还会提供一个有用的调试器(可以执行任意代码),下面的命令就可以开启调试模式:
$ export FLASK_ENV=development
$ flask run
关于调试,还可以在应用中使用test_request_context()
环境管理器来进行单元测试,使用with
语句可以绑定一个测试请求,例如:
from flask import request
with app.test_request_context('/hello', method='POST'):
# now you can do something with the request until the
# end of the with block, such as basic assertions:
assert request.path == '/hello'
assert request.method == 'POST'
0x03 关于路由
之前有提到,使用@app.route()
装饰器就可以把一个URL绑定到某个函数上,那个函数的返回值就是显示在页面上的内容,这其实就是Flask的路由方式。(路由是可以叠加的)
(需要注意的是如果指定了路径,比如@app.route('/post/')
,一定要在最后加上一个/
否则这个post就会被当成一个路径去访问)
同时,路由之中可以使用methods
参数来处理不同的HTTP方法(默认只处理GET),以下是一个例子
from flask import request
app = Flask(__name__)
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
pass
else:
pass
URL变量
路由中给出的URL可以使用变量,格式为<converter:variable_name>
,变量名可以被作为参数传入处理函数中
string |
(缺省值) 接受任何不包含斜杠的文本 |
---|---|
int |
接受正整数 |
float |
接受正浮点数 |
path |
类似 string ,但可以包含斜杠 |
uuid |
接受 UUID 字符串 |
例如
@app.route('/userinfo/<string:username>')
def userinfo(username):
return 'Welcome %s' % escape(username)
使用 url_for 构建URL
url_for()
可以用来构造指定函数的URL,例如有这样一个路由
@app.route('/login')
def login():
pass
@app.route('/userinfo/<username>')
def profile(username):
pass
此时我们如果使用url_for
,就可以构造出如下URL:
url_for('login') # /login
url_for('login', next='/') # /login?next=/
url_for('profile', username='DiaosSama') # /userinfo/DiaosSama
动态建立URL的好处就不用多说了,当使用动态变量更改URL时,相比于把URL写死在模板中,动态建立更加方便,需要修改的地方也更少
0x04 页面渲染
作为一个框架,它就一定有渲染html页面的功能,Flask这个框架也不例外
静态文件
想要使用静态文件,比如css
或者js
的时候,只需要将它们放在/static
文件夹下,并使用url_for()
就可以生成相应的URL
url_for('static', filename='style.css') # static/style.css
渲染模板页面
使用render_template()
方法就可以渲染模板,只需要提供模板名称和需要作为参数传递给模板的变量就行了,flask中内置了Jinja2模板引擎用以渲染模板,所以一些模板的语法可以在Jinja2的文档中找到
from flask import render_template
@app.route('/hello/')
@app.route('/hello/<name>')
def hello(name=None):
return render_template('hello.html', name=name)
模板文件默认放在templates
文件夹中
0x05 重定向和错误
使用 redirect()
函数可以重定向。使用 abort()
可以 更早退出请求,并返回错误代码:
from flask import abort, redirect, url_for
@app.route('/')
def index():
return redirect(url_for('login'))
@app.route('/login')
def login():
abort(401)
this_is_never_executed()
上例实际上是没有意义的,它让一个用户从索引页重定向到一个无法访问的页面(401 表示禁止访问)。但是上例可以说明重定向和出错跳出是如何工作的。
缺省情况下每种出错代码都会对应显示一个黑白的出错页面。使用 errorhandler()
装饰器可以定制出错页面:
from flask import render_template
@app.errorhandler(404)
def page_not_found(error):
return render_template('page_not_found.html'), 404
注意 render_template()
后面的 404
,这表示页面对应的出错 代码是 404 ,即页面不存在。缺省情况下 200 表示:一切正常。
0x06 结语
第一部分学习先到这里吧,下一部分的学习着重在处理请求方面,即Flask中的request
模块
本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!