• 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数据返回给浏览器

  • 相关阅读:
    Java中使用Base64编码URL
    JSON Web Token (JWT)入门学习
    1047. 删除字符串中的所有相邻重复项
    1021. 删除最外层的括号
    使用shell获取随机端口<帮你解决端口的占用烦恼>
    初始化一个vue项目并生成完整的目录结构
    mysql-常用字符函数
    设计模式-单例模式-饿汉和懒汉
    Java-指令的重排序
    Java-反射类加载到内存分析
  • 原文地址:https://www.cnblogs.com/Hannibal-2018/p/11229520.html
Copyright © 2020-2023  润新知