文章目录
1.Web开发危机四伏
攻陷Web应用的手段五花八门。Flask可保护Web应用中常见的安全问题:
跨站脚本攻击(XSS)。Flask和底层的Jinja2应付的很好。
开发者必须在为需求编写代码时留心安全隐患,在这点上Flask和其他框架没有区别。
2.安装
Flask依赖两个外部库:Werkzug和Jinja2。Werkzug是一个WSGI(在Web应用和多种服务器之间的标准Python接口)工具集。Jinja2负责渲染模板。
virtualenv
virtualenv解决了什么问题?当你拥有项目越多,同时使用不同版本的Python版本的Python工作的可能性越大,或者起码需要不同版本的Python库。
问题就出现在这里,常常有不同的库会破坏向后兼容性,然而正经应用不采用外部库的可能微乎其微,当在你的项目中,出现两个或者更多的依赖冲突时候,就需要使用到virtualenv了。
virtualenv为每个不同的项目提供一份Python安装。它并没有安装多个Python副本,但是它确实提供了一种巧妙的方式让各个项目环境保持独立。
3.快速入门
一个最小的Flask应用
from flask import Flask
app=Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello world'
if __name__=="__main__":
app.run()
将上面的代码保持为hello.py,然后用python解释器来运行。
python hello.py
* Running on http://127.0.0.1:5000/
访问http://127.0.0.1:5000/就可以看到Hello World问候
那么这段代码做了什么?
- 首先,我们导入了Flask类。这个类的实例将会是我们的WSGI应用程序。
- 接下来,创建了一个Flask类的实例,命名为app。第一个参数是应用模块名称或包的名称。
-然后,我们使用**route()**装饰器告诉Flask什么样的url能触发我们的函数。 - 这个函数名字也在生成URL时被特定的函数采用,这个函数返回我们要显示在用户浏览器中的信息.
- 最后我们用run()函数让应用运行在本地服务器上,
- 关闭服务器:Ctrl+C
外部可访问的服务器
运行了这个本地服务器,只能从自己的计算机上访问,网络中其他任何地方都访问不了。在调试模式下,用户可以在你的计算机上执行任意的Python代码。因此,这个行为是默认的
如果你禁用了debug或信任你所在的网络用户,你可以简单修改如下代码
app.run(host='0.0.0.0')
这会让操作系统监听所有公网IP.
路由
route()装饰器把一个函数绑定到对应的URL上。
同时,route还可以构造含有动态部分的URL,也可以在一个函数上附着多个规则。
变量规则
要给URL添加变量部分,可以把这些特殊字段标记为<variable_name>,这个部分将会作为命名参数传递到你的函数。
规则可以使用converter:variable_name指定一个可选的转换器。
@app.route('/user/<username>')
def show_user_profile(username):
# show tht user profile for that user
return 'User %s'%username
@app.route('/post/<int:post_id>')
def show_post(post_id):
# show the post with the given id ,the id is an integer
return 'Post %d'%post_id
唯一URL/重定向行为:
Flask的URL规则基于Werkzeug的路由模块。这个模块背后的思想是居于Apache以及更早的HTTP服务器主张的先例。保证优雅且唯一的URL.
构造URL
如果Flask能够匹配URL,那么Flask可以生成它们吗?当然可以。使用url_for()
from flask import Flask
app=Flask(__name__)
@app.route('/')
def index():pass
@app.route('/login/')
def login():pass
@app.route('/user/<username>')
def profile(username):pass
with app.test_request_context():
print(url_for('index'))
print(url_for('login'))
print(url_for('login',next='/'))
print(url_for('profile',username='Jhon'))
HTTP方法
HTTP(与Web应用回话的协议)有许多不同的访问URL方法。默认情况下,
路由只回应GET请求,但是通过route()装饰器传递methods参数可以改变这个行为。
@app.route('/login',methods=['GET','POST'])
def login():
if request.method=='POST':
do_the_login()
else:
show_the_login_form()
静态文件
动态Web应用也会需要静态文件,通常是CSS和JavaScript文件。理性情况下,你已经配置好Web服务器来提供静态文件,但是在开发中,Flask可以可以做到。只要在包中,或者是模块所在目录中创建一个名为static文件夹,在应用中使用/static即可访问。
给静态文件生成URL,使用特殊的’static’端点名:
url_for('static',filename='style.css')
这个文件应该存储在文件系统上的static/style.css
模块渲染
用Python生成HTML十分无趣,而且相当繁琐,应为你必须手动对HTML做转义来保证应用的安全。为此,Flask配备了Jinja2模板引擎。
使用render_template()方法来渲染模板。
from flask import render_template
@app.route('/hello/')
@app.route('hello/<name>')
def hello(name=None):
return render_template('hello.html',name=name)
Flask 会在templates文件夹里寻找模板。如果你的应用是个模块,这个
文件夹应该与模块同级;如果它是一个包,那么这个文件夹作为包的子目录。
情况1:模块:
/application.py
/templates
/hello.html
情况2:包:
/application.py
/__init.py
/templates
hello.html
一般IDE上是可以创建Flask工程的,文档结构也是自己生成的,如PyCharm
模板文件:hello.html
<!doctype html>
<title>Hello from Flask</title>
{% if name %}
<h1>Hello {{name}}!</h1>
{% endif %}
访问请求数据
对于Web应用,与客户端发送给服务器的数据及哦啊胡至关重要。在Flask找那个由全局的request对象来提供这些信息。
请求对象
from flask import request
def login():
error=None
if request.method=='POST':
if valid_login(request.form['username'],request.form['password']):
return log_the_user_in(request.form['username'])
else:
error='Invalid username/password'
return reder_template('login.html',error=error)
文件上传
用Flask处理文件上传很简单,只要确保没忘记在Html表单中设置
enctype="multipart/form-data"
不然浏览器不会发送文件;已上传的文件存储在文件系统中的一个
临时位置。你可以通过请求对象files属性访问它们。每个上传的文件都会存储在这个字典里。
from flask import request
@app.route('/upload',methods=['GET','POST'])
def upload_file():
if request.files['the_file']:
f=request.files['the_file']
f.save('/var/www/uploads/uploaded_file.txt')
Cookies
使用cookies属性来访问Cookies,用响应对象set_cookie方法来设置
Cookies。请求对象cookies属性是一个内容为客户端(比如浏览器)提交的所有Cookies的字典。
读取cookies:
from flask import request
@app.route('/')
def index('/')
username=request.cookies.get('username')
存储cookies:
from flask import make_response
app.route('/')
def index():
resp=make_response(render_template(...))
resp.set_cookie('username',the username)
return resp
重定向和错误
- 使用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()
消息闪现
反馈,是良好的应用和用户界面的重要构成。如果用户得不到足够的反馈,
他们很可能开始厌恶这个应用,Flask提供了消息闪现系统,可以简单地给用户反馈。消息闪现系统通常会在请求结束时记录信息。