flask请求钩子、HTTP响应、响应报文、重定向、手动返回错误码、修改MIME类型、jsonify()方法 --

摘要:
HTTP状态代码用于指示请求处理的结果。响应在Flask中生成。响应对象用于Flask。响应消息中的大部分内容由服务器处理。在大多数情况下,我们只负责返回主题内容。当Flask处理请求时,它将首先确定是否可以找到与请求URL匹配的路由。如果没有,它将返回404响应。如果是,请调用相应的视图函数。视图函数的返回值构成响应消息的主题内容。正确返回状态代码时,默认值为200。Flask将调用make_response()方法将视图函数的返回值转换为响应对象。

请求钩子:

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

Flask默认 实现的五种钩子:

 flask请求钩子、HTTP响应、响应报文、重定向、手动返回错误码、修改MIME类型、jsonify()方法 --第1张

示例代码:

定义了三个视图函数 A,B,C,其中C使用了after_this_request钩子,在网页中请求url 为/C,会触发C视图函数,在执行该函数的流程是先进入before_first_requst钩子,然后进入before_request钩子,之后进入C函数内部注册的after_this_request钩子函数。

之后的after_requet和teardown_request在触发响应条件时会执行。

@app.before_request
def before_request():
    print "before request"

@app.before_first_request
def before_first_request():
    print "before first request"

# @app.after_request
# def after_request(response):
#     print "after request"

@app.after_request
def per_request_callbacks(response):
    for func in getattr(g, 'call_after_request', ()):
        print "after request"
       
response = func(response)
    return response

@app.route('/A')
def A():
    return '<p> this is function A</p>'

@app.route('/B')
def B():
    return '<p>this is function B</p>'

@app.route('/C')
def C():
    @flask.after_this_request
    def after_this_request(response):
        print "after this request"
       
#raise ValueError
       
return response
    return "<p>after this request</p>"



if __name__ == '__main__':
    app.run(debug = True)

结果:

 flask请求钩子、HTTP响应、响应报文、重定向、手动返回错误码、修改MIME类型、jsonify()方法 --第2张

flask请求钩子、HTTP响应、响应报文、重定向、手动返回错误码、修改MIME类型、jsonify()方法 --第3张

http响应

Flask程序中,客户端的请求会触发相应的视图函数,获取返回值作为响应的主题,最后生成完整的响应,即响应报文

响应报文:

响应报文有协议版本、状态码、原因短语、响应首部和响应主体组成

flask请求钩子、HTTP响应、响应报文、重定向、手动返回错误码、修改MIME类型、jsonify()方法 --第4张

flask请求钩子、HTTP响应、响应报文、重定向、手动返回错误码、修改MIME类型、jsonify()方法 --第5张

响应报文的首部包含一些关于响应和服务器的信息,这些内容有Flask生成,而我们在视图函数中返回的内容即为响应报文中的主体内容。浏览器接收响应后,会把返回的响应主题解析并显示 在浏览器窗口上。

HTTP状态码用来表示请求处理的结果

 flask请求钩子、HTTP响应、响应报文、重定向、手动返回错误码、修改MIME类型、jsonify()方法 --第6张

在Flask中生成响应

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

Flask处理请求时会先判断是否可以找到与请求URL相匹配的路由,如果没有则返回404响应。如果有,则调用对应的视图函数,视图函数的返回值构成了响应报文的主题内容,正确返回时状态码默认为200,Flask会调用make_response()方法将视图函数返回值转换为响应对象。

完整的说,视图函数可以返回最多有三个元素组成的元祖:响应主题、状态码、首部字段。其中首部字段可以为字典,或是两元素元祖组成的列表([(‘Location’,’http://localhost:5000/hi’),(‘contentType’,’…’)])

flask请求成功时默认的响应码是200

flask请求钩子、HTTP响应、响应报文、重定向、手动返回错误码、修改MIME类型、jsonify()方法 --第7张

可以对请求指定不同的响应状态码:指定url为hi的请求的响应状态码为201

flask请求钩子、HTTP响应、响应报文、重定向、手动返回错误码、修改MIME类型、jsonify()方法 --第8张

结果:

flask请求钩子、HTTP响应、响应报文、重定向、手动返回错误码、修改MIME类型、jsonify()方法 --第9张

重定向

重定向可以通过修改30X响应的首部Location的字段的值来进行:

在视图函数中,return语句后面用字典的形式指定Location的值,访问的时候,会根据Location的值进行重定向

@app.route('/redirect')
def redirect():
    return "<p>This is a redirect pare</p>"

@app.route('/hello1')
def hello1():
    print "redirect..."
   
return '', 302, {'Location': 'http://127.0.0.1:5000/redirect'}
if __name__ == '__main__':
    app.run(debug = True)

结果:

 flask请求钩子、HTTP响应、响应报文、重定向、手动返回错误码、修改MIME类型、jsonify()方法 --第10张

访问hello1路径时,页面进行了重定向,重定向的位置是首部中Location字段的URL

flask请求钩子、HTTP响应、响应报文、重定向、手动返回错误码、修改MIME类型、jsonify()方法 --第11张

也可以通过Flask提供的redirect()函数来生成重定向响应

from flask import Flask,redirect

@app.route('/hello2')
def hello2():
    return redirect('http://localhost:5000/redirect')

if __name__ == '__main__':
    app.run(debug = True)

结果:

flask请求钩子、HTTP响应、响应报文、重定向、手动返回错误码、修改MIME类型、jsonify()方法 --第12张

修改重定向redirect函数返回码为303

@app.route('/hello2')
def hello2():
    return redirect('http://localhost:5000/redirect',303)

if __name__ == '__main__':
    app.run(debug = True)

结果:

 flask请求钩子、HTTP响应、响应报文、重定向、手动返回错误码、修改MIME类型、jsonify()方法 --第13张

程序内重定向到其他视图函数

如果要在程序内重定向到其他视图函数,可以在redirect()函数中使用url_for()函数生成目标URL,可以在响应首部的Location看到重定向的目标URL,重定向到其他视图其实就是重定向到该视图对应的url

from flask import Flask,redirect,url_for

@app.route('/hello3')
def hello3():
    return redirect(url_for('redirect'))#重定向到/redirect

@app.route('/redirect')
def redirect():
    return "<p>This is a redirect pare</p>"

if __name__ == '__main__':
    app.run(debug = True)

结果:

flask请求钩子、HTTP响应、响应报文、重定向、手动返回错误码、修改MIME类型、jsonify()方法 --第14张

手动返回错误响应

大多数情况下,Flask会自动处理常见的错误响应。HTTP错误对应的异常类在Werkzeug的werkzeug.exceptions模块中定义,抛出这些异常即可返回对应的错误响应。如果你想手动返回错误响应,可以使用Flask提供的abort()函数。

在abort()函数中传入状态码即可返回对应的错误响应。

需要注意,abourt()函数被调用后,abort()函数之后的代码不会被执行。

例子为手动返回404错误:

from flask import abort

@app.route('/404')
def not_found():
    abort(404)



if __name__ == '__main__':
    app.run(debug = True)

结果:

flask请求钩子、HTTP响应、响应报文、重定向、手动返回错误码、修改MIME类型、jsonify()方法 --第15张

响应格式:

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

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

MIME类型

MIME类型(又称media type或content type)是一种用来表示文件类型的机制,它与文件扩展名相对应,可以让客户端区分不同的内容类型,并执行不同的操作。一般的格式为“类型名/子类型名”。其中子类型名一般为文件扩展名。比如HTML的MIME类型为”text/html”,png图片的MIME类型为”image/png”。

如果想使用其他MIME类型,可以通过Flask提供的make_response()方法生成响应对象,传入响应的主体作为参数,然后使用响应对象的mimetype属性设置MIME类型,不需要设置字符集(charset)选项。

修改MIME类型:

from flask import make_response

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

结果:

flask请求钩子、HTTP响应、响应报文、重定向、手动返回错误码、修改MIME类型、jsonify()方法 --第16张

常用的数据格式(纯文本、HTML、XML和JSON)对应的MIME类型

纯文本的MIME类型:text/plain

HTML的MIME类型:text/html

XML的MIME类型:application/xml

JSON的MIME类型:application/json

Flask提供JSON的支持

Flask通过引入Python标准库中的json模块为程序提供了JSON支持。你可以直接从Flask中导入json对象,然后调用dumps()方法将字典、列表或元祖序列化为JSON字符串,在使用前面介绍的方法修改MIME类型,即可返回JSON响应

例如:

用json模块把响应转换为JSON

from flask import Flask,make_response,json

@app.route('/foo1')
def foo1():
    data={'name':'Sam Xia','gender':'male'}
    response = make_response(json.dumps(data))
    response.mimetype = 'application/json'
   
return response

if __name__ == '__main__':
    app.run(debug = True)

结果:

 flask请求钩子、HTTP响应、响应报文、重定向、手动返回错误码、修改MIME类型、jsonify()方法 --第17张

也可以jsonnify()方法转换响应内容为JSON

不过我们一般并不直接使用json模块的dumps()、load()等方法,因为Flask通过包装这些方法提供了更方便的jsonify()函数。用jsonify()函数,我们进需要传入数据或参数,他会把传入的参数转化成JSON字符串作为响应的主体,然后生成一个响应对象,并且设置正确的MIME类型。

例如:

@app.route('/foo3')
def foo3():
    return jsonify(name = 'Sam Xia',gender = 'make')

if __name__ == '__main__':
    app.run(debug = True)

结果:

flask请求钩子、HTTP响应、响应报文、重定向、手动返回错误码、修改MIME类型、jsonify()方法 --第18张

jsonify()函数可以接收多种形式的参数。可以传入如上边的关键字参数,也可以像dumps()方法一样传入字段、列表或元祖,如:


from flask import jsonify

@app.route('/foo3')
def foo3():
    return jsonify({'name':'Sam Xia','gender' : 'make'})#传入字典

if __name__ == '__main__':
    app.run(debug = True)

结果:

flask请求钩子、HTTP响应、响应报文、重定向、手动返回错误码、修改MIME类型、jsonify()方法 --第19张

jsonify()函数可以自定义响应码

from flask import jsonify

@app.route('/foo3')
def foo3():
    return jsonify(message = 'Error !'),500
if __name__ == '__main__':
    app.run(debug = True)

结果:

 flask请求钩子、HTTP响应、响应报文、重定向、手动返回错误码、修改MIME类型、jsonify()方法 --第20张

免责声明:文章转载自《flask请求钩子、HTTP响应、响应报文、重定向、手动返回错误码、修改MIME类型、jsonify()方法 --》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Web_add_cookie的作用HTTP网页错误代码大全(如404,500,403)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Python的魔法函数

概要 如何定义一个类 类里通常包含什么 各个部分解释 类是怎么来的 type和object的关系 判断对象的类型 上下文管理器 类结构 #!/usr/bin/env python #-*- coding: utf-8 -*- #Author: rex.cheny #E-mail: rex.cheny@outlook.com #类名后面写(object...

asp.net C#后台实现下载文件的几种方法(全)

protected void Button1_Click(object sender, EventArgs e) { /* 微软为Response对象提供了一个新的方法TransmitFile来解决使用Response.BinaryWrite 下载超过400mb的文件时导致Aspnet_wp.exe进程回收而无法成功下载的问题。 代码如下: */ Res...

idea运行main方法或Test避免编译整个应用的方法

在idea,我常常会遇到这样的问题,我写个main或者Test,明明就想运行一个简单的函数测试下某个简单的方法,但一运行就需要编译整个项目,非常的耗时 这里我给出一个idea简单的修改配置就可以解决问题,我的idea版本是2021.2,其它版本可以参考也是类似的 如下所示: 把Do not build before run勾上 自动编译勾上(PS:juni...

docker 部署 flask(一)配置环境及测试

简介: flask也是要部署的。不能老在我们的pycharm里面跑测试服务器。 各种配置linux,我看就算了吧。我们用docker部署。 也就两三行命令。 一:选择基础镜像 GitHub repo: https://github.com/tiangolo/uwsgi-nginx-flask-docker Docker...

Vert X 干法总结

Vert X优势:   1. 与基于阻塞 I/O 的传统堆栈和框架相比,以更少的资源处理更多的请求。Vert.x 非常适合各种执行环境,包括虚拟机和容器等受限环境。   2. Vert.x 是一个工具包,不是一个框架,所以它自然是非常可组合和可嵌入的(不同语言都可以)。     Vert.x运行在Java虚拟机上,支持多种编程语言,Vert.x是高度模块化...

spring boot 重定向

/** * 测试各个html文件用。 * @param model * @return */ @RequestMapping("home") public String home(RedirectAttributes model) { model.addAttribute("...