flask读书记录

1. 在flask中,如果我们在视图函数中使用data = request.get_json()方法获取数据,那么在客户端发送POST请求时,就需要设置设置正确的Content-Type首部。在ajax()函数中,Content-Type首部使用contentType参数设置,JSON对应的值为'application/json;charset=UTF-8'。

注:当数据以GET方法提交时,会和往常一样以查询字符串的形式附加在请求URL中。在视图函数中,我们可以通过request.args属性获取。而在提交POST请求时,如果你没有指定内容类型为JSON,那么数据会以默认的表单类型(即application/xwww-form-urlencoded)提交,在视图函数中需要从request.form属性中获取数据。

理解为,前段发送时指定了发送的是什么格式的数据类型,那么后端接收时就需要根据对应的数据类型去接收。

JSON.parse() : 将json格式的字符串转化为js对象。

JSON.stringify():将js对象转化为json格式的字符串。

2. 我们学习了使用Flask-WTF扩展提供的CSRFProtect扩展设置全局CSRF保护,但是Web API中的视图并不需要使用CSRF防护,因为Web API并不使用cookie认证用户。我们可以使用csrf.exempt()方法来取消对API蓝本的CSRF保护,它接收蓝本对象作为参数:

from todoism.apis.v1 import api
def register_extensions(app):
...
csrf.init_app(app)
csrf.exempt(api)

3. 添加CORS支持

在介绍CORS(Cross Origin Resource Sharing,跨域资源共享)之前,我们需要先了解一下同源策略(Same origin policy)。出于安全考虑,浏览器会限制从脚本内发起的跨域请求。这里的跨域包括不同域名、不同端口、不同HTTP模式(HTTP、HTTPS等)。比如,从exampleA.com向exampleB.com发起的请求就属于跨域请求。

当API蓝本设置了子域后,假设我们的Web API部署在api.example.com中,而程序部署在www.example.com中,这时从www.example.com向API发起的AJAX请求就会因为同源策略而失败。对于向第三方大范围公开的API,更要考虑支持CORS。

CORS需要同时被浏览器和服务器支持,大多数浏览器都支持CORS,我们只需要在服务器端设置支持CORS。我们可以使用扩展Flask-CORS来为API添加跨域访问支持,先使用Pip进行安装:

pip install flask-cors

因为我们只需要对API蓝本中的路由添加跨域请求支持,所以以Flask-CORS扩展只在蓝本中初始化,传入蓝本对象作为参数:

from flask import Blueprint
from flask_cors import CORS
api_v1 = Blueprint('api_v1', __name__)
CORS(api_v1)

默认情况下,Flask-CORS会为蓝本下的所有路由添加跨域请求支持,并且允许来自任意源的跨域请求。

4. 注册路由

在一个Web应用里,客户端和服务器上的Flask程序的交互可以简单概括为以下几步:
1)用户在浏览器输入URL访问某个资源。
2)Flask接收用户请求并分析请求的URL。
3)为这个URL找到对应的处理函数。
4)执行函数并生成响应,返回给浏览器。
5)浏览器接收并解析响应,将信息显示在页面中。
在上面这些步骤中,大部分都由Flask完成,我们要做的只是建立处理请求的函数,并为其定义对应的URL规则。只需为函数附加app.route()装饰器,并传入URL规则作为参数,我们就可以让URL与函数建立关联。这个过程我们称为注册路由(route),路由负责管理URL和函数之间的映射,而这个函数则被称为视图函数(viewfunction)。

@app.route('/')
def index():
    return '<h1>Hello, World!</h1>'

route()装饰器的第一个参数是URL规则,用字符串表示,必须以斜杠(/)开始。这里的URL是相对URL(又称为内部URL),即不包含域名的URL。以域名www.helloflask.com为例,“/”对应的是根地址(即www.helloflask.com),如果把URL规则改为“/hello”,则实际的绝对地址(外部地址)是www.helloflask.com/hello。

当URL规则中包含变量时,如果用户访问的URL中没有添加变量,比如/greet,那么Flask在匹配失败后会返回一个404错误响应。一个很常见的行为是在app.route()装饰器里使用defaults参数设置URL变量的默认值,这个参数接收字典作为输入,存储URL变量和默认值的映射。在下面的代码中,我们为greet视图新添加了一个app.route()装饰器,为/greet设置了默认的name值:

@app.route('/greet', defaults={'name': 'Programmer'})
@app.route('/greet/<name>')
def greet(name):
    return '<h1>Hello, %s!</h1>' % name

这时如果用户访问/greet,那么变量name会使用默认值Programmer,视图函数返回<h1>Hello,Programmer!</h1>。

5. Flask命令

除了Flask内置的flask run等命令,我们也可以自定义命令。在虚拟环境安装Flask后,包含许多内置命令的flask脚本就可以使用了。

通过创建任意一个函数,并为其添加app.cli.command()装饰器,我们就可以注册一个flask命令。

@app.cli.command()
def hello():
click.echo('Hello, Human!')

函数的名称即为命令名称,这里注册的命令即hello,你可以使用flask hello命令来触发函数。作为替代,你也可以在app.cli.command()装饰器中传入参数来设置命令名称,比如app.cli.command('say-hello')会把命令名称设置为say-hello,完整的命令即flask say-hello。
借助click模块的echo()函数,我们可以在命令行界面输出字符。命令函数的文档字符串则会作为帮助信息显示(flask hello--help)。在命令行下执行flask hello命令就会触发这个hello()函数。

6. Request对象

现在该让Flask的请求对象request出场了,这个请求对象封装了从客户端发来的请求报文,我们能从它获取请求报文中的所有数据。

 

7. 请求钩子

有时我们需要对请求进行预处理(preprocessing)和后处理(postprocessing),这时可以使用Flask提供的一些请求钩子(Hook),它们可以用来注册在请求处理的不同阶段执行的处理函数(或称为回调函数,即Callback)。这些请求钩子使用装饰器实现,通过程序实例app调用,用法很简单:以before_request钩子(请求之前)为例,当你对一个函数附加了app.before_request装饰器后,就会将这个函数注册为before_request处理函数,每次执行请求前都会触发所有before_request处理函数。

@app.before_request
def do_something():
 pass # 这里的代码会在每个请求处理前执行

after_request钩子和after_this_request钩子必须接收一个响应类对象作为参数,并且返回同一个或更新后的响应对象。

8. 响应报文

响应报文

常见的HTTP状态码

9. 在Flask中生成响应

响应在Flask中使用Response对象表示,响应报文中的大部分内容由服务器处理,大多数情况下,我们只负责返回主体内容。

根据我们在上一节介绍的内容,Flask会先判断是否可以找到与请求URL相匹配的路由,如果没有则返回404响应。如果找到,则调用对应的视图函数,视图函数的返回值构成了响应报文的主体内容,正确返回时状态码默认为200。Flask会调用make_response()方法将视图函数返回值转换为响应对象。
完整地说,视图函数可以返回最多由三个元素组成的元组:响应主体、状态码、首部字段。其中首部字段可以为字典,或是两元素元组组成的列表。

普通的响应可以只包含主体内容:

@app.route('/hello')
def hello():
...
return '<h1>Hello, Flask!</h1>'

默认的状态码为200

指定了不同的状态码:

@app.route('/hello')
def hello():
...
return '<h1>Hello, Flask!</h1>', 201

有时你会想附加或修改某个首部字段。比如,要生成状态码为3XX的重定向响应,需要将首部中的Location字段设置为重定向的目标URL:

@app.route('/hello')
def hello():
...
return '', 302, {'Location', 'http://www.example.com'}

现在访问http://localhost:5000/hello,会重定向到http://www.example.com。在多数情况下,除了响应主体,其他部分我们通常只需要使用默认值即可。

对于重定向这一类特殊响应,Flask提供了一些辅助函数。除了像前面那样手动生成302响应,我们可以使用Flask提供的redirect()函数来生成重定向响应,重定向的目标URL作为第一个参数。前面的例子可以简化为:

from flask import Flask, redirect
# ...
@app.route('/hello')
def hello():
return redirect('http://www.example.com')

使用redirect()函数时,默认的状态码为302,即临时重定向。

10. 响应格式

在HTTP响应中,数据可以通过多种格式传输。大多数情况下,我们会使用HTML格式,这也是Flask中的默认设置。在特定的情况下,我们也会使用其他格式。不同的响应数据格式需要设置不同的MIME类型,MIME类型在首部的Content-Type字段中定义,以默认的HTML类型为例:

Content-Type: text/html; charset=utf-8

MIME类型(又称为media type或content type)是一种用来标识文件类型的机制,它与文件扩展名相对应,可以让客户端区分不同的内容类型,并执行不同的操作。

如果你想使用其他MIME类型,可以通过Flask提供的make_response()方法生成响应对象,传入响应的主体作为参数,然后使用响应对象的mimetype属性设置MIME类型,比如:

from flask import make_response
@app.route('/foo')
def foo():
response = make_response('Hello, World!')
response.mimetype = 'text/plain'
return response

你也可以直接设置首部字段,比如response.headers['Content-Type']='text/xml;charset=utf-8'。但操作mimetype属性更加方便,而且不用设置字符集(charset)选项。

常用的数据格式有纯文本、HTML、XML和JSON,下面我们分别对这几种数据进行简单的介绍和分析。

1.纯文本
MIME类型:text/plain

事实上,其他几种格式本质上都是纯文本。比如同样是一行包含HTML标签的文本“<h1>Hello,Flask!</h1>”,当MIME类型设置为纯文本时,浏览器会以文本形式显示“<h1>Hello,Flask!</h1>”;当MIME类型声明为text/html时,浏览器则会将其作为标题1样式的HTML代码渲染。

2.HTML
MIME类型:text/html

3.XML
MIME类型:application/xml

<?xml version="1.0" encoding="UTF-8"?>
<note>
<to>Peter</to>
<from>Jane</from>
<heading>Reminder</heading>
<body>Don't forget the party!</body>
</note>

4.JSON
MIME类型:application/json

JSON(http://json.org/)指JavaScript Object Notation(JavaScript对象表示法),是一种流行的、轻量的数据交换格式

Flask通过包装这些方法提供了更方便的jsonify()函数。借助jsonify()函数,我们仅需要传入数据或参数,它会对我们传入的参数进行序列化,转换成JSON字符串作为响应的主体,然后生成一个响应对象,并且设置正确的MIME类型。

jsonify()函数默认生成200响应,你也可以通过附加状态码来自定义响应类型,比如:

@app.route('/foo')
def foo():
return jsonify(message='Error!'), 500

11. AJAX相关

ajax()函数支持的参数













 

 


















 

猜你喜欢

转载自www.cnblogs.com/yuqiangli0616/p/10233536.html