Flask-1-05-Response

如果在执行后端代码的时候,用户的访问不能满足你规定的要求的时候,你还想给用户一个反馈,这里就可以使用abort函数,立即终止视图函数的执行,并返回给前端特定的信息

例如这里我们模拟,用户访问首页的时候,需要先登录,跳转到登录页面后,模拟用户输入的请求是错误,我们返回给他401的状态(禁止访问)

# coding:utf-8
from flask import Flask, redirect, url_for, abort # 这里我们需要导入abort这个类

app = Flask(__name__)


@app.route('/')
def index():
    # 将视图重定向到login页面
    return redirect(url_for('login'))


def this_is_never_excuted():
    # 永远不会被执行
    pass


@app.route("/login", methods=['GET'])
def login():
    # 模拟登陆失败, 返回401意为着禁止访问
    abort(401)
    print('永远不会去执行')
    this_is_never_excuted()


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

 返回结果:

这里可以看出返回的状态码是401说明,我们abort函数执行了,通过后台返回的信息也能看出,abort函数之后的代码也没有执行,下面就是服务端的返回信息:

(Flask_py) python@python-VirtualBox:~/code$ python abort_demo.py 
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 294-731-034
192.168.3.5 - - [23/Jul/2019 07:41:58] "GET / HTTP/1.1" 302 -
192.168.3.5 - - [23/Jul/2019 07:41:58] "GET /login HTTP/1.1" 401 -
192.168.3.5 - - [23/Jul/2019 07:41:58] "GET /favicon.ico HTTP/1.1" 404 -

通过源码我们可以看到abort函数给出的注释里还有一种应用方法

'''
Can be passed a WSGI application or a status code. If a status code is
given it's looked up in the list of exceptions and will raise that
exception, if passed a WSGI application it will wrap it in a proxy WSGI
exception and raise that::

abort(404)
abort(Response('Hello World'))

'''

大概翻译的就是

你可以传递一个WSGI应用或者是一个状态码。如果给定一个状态码,它会在异常列表中查找并引发异常,如果传递的是一个WSGI应用,它将把它包装在一个代理WSGI异常中并引发该异常

# abort 的另一种应用方法
from flask import Flask, redirect, url_for, abort, Response # 需要导入的包

app = Flask(__name__)


@app.route('/')
def index():
    # 将视图重定向到login页面
    return redirect(url_for('login'))


def this_is_never_excuted():
    # 永远不会被执行
    pass


@app.route("/login", methods=['GET'])
def login():
    # 模拟登陆失败, 返回401意为着禁止访问
    # abort(401)
    abort(Response('禁止访问!!!'))
    print('永远不会去执行')
    this_is_never_excuted()


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

这里并不是抛出状态码给定的HTTPException,所以浏览器默认认为,它只是执行了, 我们想给定的结果,所以状态码是200,现在我们使用到的都是默认给出的状态码返回的信息,比如页面未找到会抛出一个404的状态码。如果你要定制错误页面,这里就可以使用errorhandler() 装饰器:

# coding:utf-8
from flask import Flask, redirect, url_for, abort, Response

app = Flask(__name__)


@app.route('/')
def index():
    # 将视图重定向到login页面
    return redirect(url_for('login'))


def this_is_never_excuted():
    # 永远不会被执行
    pass


@app.route("/login", methods=['GET'])
def login():
    # 模拟登陆失败, 返回401意为着禁止访问
    abort(404)
    # abort(Response('禁止访问!!!'))
    # print('永远不会去执行')
    # this_is_never_excuted()

# 自定义错误视图,用来返回给前端用户看到的结果
@app.errorhandler(404)
def page_not_found(error):
    return "页面未找到 %s" % error, 404


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

 访问127.0.0.1:5000/ 会返回的结果是:因为这里跳转到登录页面之后会直接执行abort(404)

这就是通过我们自己定制给出的返回结果

 

响应


 

视图函数的返回值会被自动转换为一个响应对象。如果返回值是一个字符串, 它被转换为该字符串为主体的、状态码为 200 OK``的 、 MIME 类型是 ``text/html 的响应对象。Flask 把返回值转换为响应对象的逻辑是这样:

  1. 如果返回的是一个合法的响应对象,它会从视图直接返回。

  2. 如果返回的是一个字符串,响应对象会用字符串数据和默认参数创建。

  3. 如果返回的是一个元组,且元组中的元素可以提供额外的信息。这样的元组必须是 (response, status, headers) 的形式,且至少包含一个元素。 status 值会覆盖状态代码, headers 可以是一个列表或字典,作为额外的消息标头值。

  4. 如果上述条件均不满足, Flask 会假设返回值是一个合法的 WSGI 应用程序,并转换为一个请求对象。

如果你想在视图里操纵上述步骤结果的响应对象,可以使用 make_response() 函数。

接下来定义一个index视图,分别展示一下返回响应的信息和自定义的状态码

# coding:utf-8
from flask import Flask, make_response

app = Flask(__name__)

@app.route("/index")
def index():
    # 1 使用元祖,返回自定义的响应信息
    #          响应体     状态码                  响应头
    # return "index page", 400, [("Programme_L", "python"), ("Locality", "Harbin")]
    # return "index page", 400, {"Programme_L": "python", "Locality": "Harbin"}
    # return "index page", "666 userDefined status", {"Programme_L": "python", "Locality": "Harbin"}
    # return "index page", "666 userDefined status"

    # 2 使用make_response 响应信息
    resp = make_response("index page 2")
    resp.status = "999 userDefined"  # 设置状态码
    resp.headers["city"] = "Harbin"  # 设置响应头
    return resp


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

这里只给大家展示用make_response 响应的结果:

 

 

返回 json 数据

在学习Python的时,其中有一个json模块可以帮我们将字典数据转换成 json字符串【json.dumps(dict)】,也可以将字符串转换成Python中的字典【json.loads(str)】,显然我们这里就可以这样使用

# coding:utf-8
import json

from flask import Flask

app = Flask(__name__)

@app.route("/index")
def index():
    data = {
        'name': 'circle',
        'age': 30,
    }
    json_str = json.dumps(data)
    return json_str, 200, {"Content-Type": "application/json"}  # 这里我们一定要手动添加这句话来指定为json数据

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

虽然我们这样自己指定也是很方便的就可以将json数据返回,但是我们还是需要手动添加{"Content-Type": "application/json"}  来指定为json数据,这里我们使用Flask框架帮我封装的 jsonify() 就可以完成更简便的操作

# coding:utf-8
from flask import Flask, jsonify

app = Flask(__name__)

@app.route("/index")
def index():
    data = {
        'name': 'circle',
        'age': 30,
    }
    # json_str = json.dumps(data)
    # return json_str, 200, {"Content-Type": "application/json"}
    return jsonify(data)


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

通过返回的结果可以看出,我们可以将json数据返回给浏览器

 

posted @ 2019-07-23 08:02  Hannibal_2018  阅读(122)  评论(0编辑  收藏  举报