隐式响应:

1. 视图函数的返回值会被隐式转换为一个响应对象

2. 如果返回的是一个合法的响应对象,则会从视图函数中直接返回

3. 如果返回的是一个字符串,会用字符串数据和默认参数创建字符串为主体,状态码为200,MIME类型为text/html的werkzeug.wrappers.Response响应对象

4. 如果返回的是一个元组(response, status, headers),且至少包含一个元素,status值会覆盖状态代码,headers可以是一个列表或是字典,作为额外的消息头

5. 如果上述条件均不满足,Flask会通过werkzeug.wrappers.Response.force_type(rv, request.environ)强制返回


#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
#
# Authors: limanman
# 51CTOBG: http://xmdevops.blog.51cto.com/
# Purpose:
#
"""
# 说明: 导入公共模块
from flask import Flask, render_template, make_response
# 说明: 导入其它模块
app = Flask(__name__)
@app.errorhandler(404)
def not_found(error):
    return render_template('errors/404.html'), 404


显式响应:


说明: 显式响应就是通过flask.make_response来创建响应对象,它接收三个参数,response, status, headers然后返回响应对象,可以通过调用rsp.set_cookie(key, value='', max_age=None, expires=None, path='/', domain=None, secure=None, httponly=False)和rsp.delete_cookie(key, path='/', domain=None)来设置或删除cookie,还可以通过添加额外头部信息返回


#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
#
# Authors: limanman
# 51CTOBG: http://xmdevops.blog.51cto.com/
# Purpose:
#
"""
# 说明: 导入公共模块
from flask import Flask, render_template, make_response
# 说明: 导入其它模块
app = Flask(__name__)
@app.errorhandler(404)
def server_err(error):
    return make_response(render_template('errors/404.html'), 500)
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=9000, debug=True)

说明: 其实更加推荐使用make_response显式响应,因为其可以返回一个响应对象,可以通过响应对象做很多事情,如设置浏览器客户端cookie等


自定响应:


#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
#
# Authors: limanman
# 51CTOBG: http://xmdevops.blog.51cto.com/
# Purpose:
#
"""
# 说明: 导入公共模块
import json
from flask import Flask, request, make_response
from werkzeug.wrappers import Response
# 说明: 导入其它模块
class JSONPResponse(Response):
    @classmethod
    def force_type(cls, response, environ=None):
        if isinstance(response, dict):
            response = '{0}({1})'.format(response.get('callback'), json.dumps(response.get('data')))
            response = make_response(response)
        return super(JSONPResponse, cls).force_type(response, environ)
app = Flask(__name__)
app.response_class = JSONPResponse
@app.route('/api/hosts/jsonp')
def jsonp():
    rm_hosts = ['192.168.1.1', '192.168.1.2', '192.168.1.3',
                '192.168.1.4', '192.168.1.5', '192.168.1.6']
    callback = request.args.get('callback')
    return {'callback': callback, 'data': rm_hosts}
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=9000, debug=True)



    
        
        JSONP
    
    
        
        
    

说明: 如上通过自定义响应实现了一个JSNP跨域,需要注意的是继承自Response类时只需要重写一个BaseResponse基类的force_type类方法,force_type接收两个参数,一个是视图函数返回的原始数据,一个是请求对象信息,如果为空默认使用的是request.environ,但是需要注意由于我们自定义的字典式响应并不满足默认响应条件,所以会自动调用Response.force_type(response, request.environ)来转换为一个请求对象,所以上面我们使用使用了make_response(response)直接生成了一个响应对象传递给基类的.force_type方法来生成响应


http GET http://127.0.0.1:9000/api/hosts/jsonp callback==hostsCallback
HTTP/1.0 200 OK
Content-Length: 105
Content-Type: text/plain; charset=utf-8
Date: Thu, 27 Oct 2016 03:09:32 GMT
Server: Werkzeug/0.11.11 Python/2.7.11
hostsCallback(["192.168.1.1", "192.168.1.2", "192.168.1.3", "192.168.1.4", "192.168.1.5", "192.168.1.6"])