Flask--请求和响应

请求对象

  • Flask从环境变量中获取请求数据并储存在request代理对象上了,主要基于Request类实现
1. GET请求
  • 获取get请求的参数:request.args
  • 获取的数据类型:ImmutableMultiDict(不可变字典)
  • 可以用 to_dict() 方法转换成普通的可变字典
@app.route('/')
def index():
    r = request.args
    print(r.get('id'))  # 1
    return r.to_dict()  # json格式:{"id": 1}
curl -X GET "http://127.0.0.1:5000/?id=1"
{
  "id": "1"
}
2. POST请求
  • form
  • 获取表单数据,请求头是:application/x-www-form-urlencoded
  • 获取表单数据:request.form
  • 获取的数据类型:ImmutableMultiDict(不可变字典)
@app.route('/', methods=['POST'])
def index():
    return request.form
# post请求发送data格式数据
$ curl http://127.0.0.1:5000 -X POST -d 'id=1&name=zhangsan' 
{
  "id": "1", 
  "name": "zhangsan"
}
  • json
  • 获取json数据,请求头是:applocation/json
  • 获取json数据:request.json
  • 数据类型:普通字典dict类型,内部帮我们用json.loads(data)转换dict类型
  • 其实内部是调用的get_json()方法
@app.route('/', methods=['POST'])
def index():
    return request.json
# post请求发送json格式数据
$ curl http://127.0.0.1:5000 -X POST -d '{"id": "1","name":"zhangsan"}' -H "Content-Type:application/json"
{
  "id": "1", 
  "name": "zhangsan"
}
3. 其他参数
  • request.values
  • 可以同时获取args参数和form表单参数
  • 类型是CombinedMultiDict,内容是args和form
  • 一样可根据字典的方法获取对应的参数名的值
@app.route('/', methods=['POST', 'GET'])
def index():
    return request.values
# get请求
$ curl http://127.0.0.1:5000 -X GET -d 'id=1&name=zhangsan' 
{
  "id": "1", 
  "name": "zhangsan"
}
# post请求
$ curl http://127.0.0.1:5000 -X POST -d 'id=1&name=zhangsan' 
{
  "id": "1", 
  "name": "zhangsan"
}
  • request.cookies
  • 获取请求头的cookie数据,类型是dict
@app.route('/', methods=['POST', 'GET'])
def index():
    return request.cookies
# cur命令发送cookie数据
$ curl http://127.0.0.1:5000 -X POST -d 'id=1&name=zhangsan' --cookie "user=root;pwd=123456"
{
  "pwd": "123456", 
  "user": "root"
}
  • request.headers
  • 获取请求头类型dict
  • request.data
  • 包含传入的请求数据作为字符串,以防它与 Werkzeug无法处理mimetype。
  • 可以获取json数据,但获取出来的数据类型bytes
  • request.files:比较重要
  • 获取post或put请求的文件
  • 类型MultiDict
  • request.environ
  • 获取WSGI隐含的环境配置
  • 可以获取request对象没有封装的数据
  • request.method
  • 获取请求方法
  • request.remote_addr
  • 获取远程ip
  • 主要用于我们要限制ip的场景下
  • reuqest.user_agent
  • 获取请求头中的user-agent数据
  • 可以做一些反扒和恶意攻击的处理
  • request.is_json
  • 判断mimetype是不是application开头,并且是json结尾
  • 布尔类型
@app.route('/', methods=['POST'])
def index():
    print(request.is_json)  # True
    return request.json
$ curl http://127.0.0.1:5000 -X POST -d '{"id": "1","name":"zhangsan"}' -H "Content-Type:application/json"
{
  "id": "1", 
  "name": "zhangsan"
}
  • request.is_xhr
  • 判断是否ajax请求发来的(要废弃了)
  • 可以通过request.environ[“HTTP_X_REQUESTED_WITH”] 来获取
    但也不一定是ajax请求,因为前端数据可伪造
@app.route('/', methods=['POST'])
def index():
    print(request.is_json)  # True
    print(request.headers)  # True
    print(request.user_agent) # curl/7.64.1
    print(request.remote_addr)  # 127.0.0.1
    print(request.method) # POST
    print(request.environ)
    # {'wsgi.version': (1, 0), 'wsgi.url_scheme': 'http', 'wsgi.input': <_io.BufferedReader name=6>, 'wsgi.errors': <_io.TextIOWrapper name='<stderr>' mode='w' encoding='utf-8'>, 'wsgi.multithread': True, 'wsgi.multiprocess': False, 'wsgi.run_once': False, 'werkzeug.server.shutdown': <function WSGIRequestHandler.make_environ.<locals>.shutdown_server at 0x7fb1bcd12430>, 'SERVER_SOFTWARE': 'Werkzeug/1.0.1', 'REQUEST_METHOD': 'POST', 'SCRIPT_NAME': '', 'PATH_INFO': '/', 'QUERY_STRING': '', 'REQUEST_URI': '/', 'RAW_URI': '/', 'REMOTE_ADDR': '127.0.0.1', 'REMOTE_PORT': 61621, 'SERVER_NAME': '127.0.0.1', 'SERVER_PORT': '5000', 'SERVER_PROTOCOL': 'HTTP/1.1', 'HTTP_HOST': '127.0.0.1:5000', 'HTTP_USER_AGENT': 'curl/7.64.1', 'HTTP_ACCEPT': '*/*', 'CONTENT_TYPE': 'application/json', 'HTTP_X_REQUESTED_WITH': 'XMLHttpRequest', 'CONTENT_LENGTH': '29', 'werkzeug.request': <Request 'http://127.0.0.1:5000/' [POST]>}
    print(request.data)  # b'{"id": "1","name":"zhangsan"}'
    print(request.environ["HTTP_X_REQUESTED_WITH"] ) # XMLHttpRequest
    return request.json
$ curl http://127.0.0.1:5000 -X POST -d '{"id": "1","name":"zhangsan"}' -H "Content-Type:application/json" -H 'X-Requested-With: XMLHttpRequest'
{
  "id": "1", 
  "name": "zhangsan"
}
  • ajax请求
@app.route('/', methods=['GET'])
def index():
    return render_template('xhr.html')

@app.route('/login', methods=['POST'])
def login():
    return request.json
<p onclick="login()">点一下试试</p>

<script type="text/javascript" src="../static/js/jquery-1.12.4.min.js"></script>
<script>
    function login(){
        $.ajax({
            url:'/login',
            type: 'post',
            dataType: 'json',
            contentType: "application/json; charset=utf-8",
            data: JSON.stringify({'username':'zhangsan', 'pwd': '123456'}),
        }).done(function(data){
            console.log(data)
            });
    };
    
</script>

响应对象

1. 响应类型Content-Type
  • 文本:text/plain
  • html:text/html。不进行任何设置时,浏览器会把响应返回的字符串变成html。
  • xml:application/xml
  • json:application/json
2. 手动构造响应返回
  • 返回json串
@app.route('/', methods=['get'])
def index():
    return json.dumps({'username': 'zhangsan', })
  • jsonify()
@app.route('/', methods=['get'])
def index():
    return jsonify({'username': 'zhangsan', })
  • 构造修改响应
@app.route('/', methods=['get'])
def index():
    return jsonify({'username': 'zhangsan', }), '204 ok', {'content-type':'application/json', 'server':'nginx'}
3. make_response()
  • 初始化构造
@app.route('/', methods=['get'])
def index():
    return make_response(json.dumps({"username": "jiangmingbai"}), '201 xx', {"content-type": "application/json"})
  • 先定义后构造
@app.route('/', methods=['get'])
def index():
    res = make_response()
    res.response = json.dumps({"username": "jiangmingbai"})
    res.status = '200 XX'
    res.header = {'a': 'b'}
    return res
4. json响应格式

+json.dumps() : <class ‘str’> ,且添加 {'Content-Type': 'application/json'}头信息之后才是json格式
+jsonify() : <class ‘flask.wrappers.Response’>

@app.route('/', methods=['get'])
def index():
    print(type(json.dumps({"username": "lis"}))).  # <class 'str'>
    return json.dumps({"username": "lis"}), '202 OK',  {'Server':'nginx', 'Content-Type': 'application/json'}
    

@app.route('/l', methods=['get'])
def indexl():
    print(type(jsonify({"username": "lisi"})))     # <class 'flask.wrappers.Response'>
    return jsonify({"username": "lisi"}), '203 OK',  {'Server':'nginx'}
5. 响应中文
  • json.dumps(dict, ensure_ascii=False) : 支持中文格式
@app.route('/')
def index():
    # return json.dumps({"username": "张三"})   # {"username": "\u5f20\u4e09"}
	return json.dumps({"username": "张三"}, ensure_ascii=False)  # {"username": "张三"}   
6. 错误响应和处理
  • return
  • 单独判断处理,错误返回异常信息
@app.route('/')
def index():
    if not request.args.get('username'):
        return make_response('没有授权','401 ERROR')
    return request.args.get('username')
  • abort
  • abort()或raise()抛出异常,并使用@app.errorhandler(code)统一拦截处理
  • 建议使用此方式,符合python 1个函数只有1个return的哲学
# 自定义401错误响应页面,配合abort使用
@app.errorhandler(401)
def error_401(error):
    return render_template("error_401.html")


@app.route('/')
def index():
    if not request.args.get('username'):
        abort(401)
    return 'success'
class LoginException(Exception):
    pass

# 自定义401错误响应页面,配合abort使用
@app.errorhandler(LoginException)
def error_401(error):
    return json.dumps({'msg': str(error)})


@app.route('/')
def index():
    if not request.args.get('username'):
        raise LoginException('not login')
    return 'success'
  • 全局错误处理
# 404全局错误封装
@app.errorhandler(404)
def page_not_fonud(error):
    # return json.dumps({'msg': "系统正在升级,请耐心等待"},ensure_ascii=False), 404
    return render_template('404.html'), 404

参考文档

  • https://www.cnblogs.com/jiangmingbai/p/13179950.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值