from flask import request
Flask 是一个人气非常高的python Web框架,笔者也拿它写过一些大大小小的项目,Flask 有一个特性我非常的喜欢,就是无论在什么地方,如果你想要获取当前的request对象,只要 简单的:
从当前request获取内容: method: 起始行,元数据 host: 起始行,元数据 path: 起始行,元数据 environ: 其中的 SERVER_PROTOCOL 是起始行,元数据 headers: 头,元数据 data: body, 元数据 remote_addr: 客户端地址 args: 请求链接中的参数(GET 参数),解析后 form: form 提交中的参数,解析后 values: args 和 forms 的集合 json: json 格式的 body 数据,解析后 cookies: 指向 Cookie 的链接
Request 对象对参数的分类很细,注意 args, form, valeus, json 的区别。当然最保险也最原始的方式就是自己去解析 data。
另一个需注意的地方是某些属性的类型,并不是 Python 标准的 dict ,而是 MultiDict 或者 CombinedMultiDict。这是为了应对 HTTP 协议中参数都是可重复的这点而做的设定。因此取值的时候要注意这些对象的特性,比如 .get() 和 .get_list() 方法返回的东西是不同的。
非常简单好记,用起来也非常的友好。不过,简单的背后藏的实现可就稍微有一些复杂了。 跟随我的文章来看看其中的奥秘吧!
两个疑问?
在我们往下看之前,我们先提出两个疑问:
疑问一 :request ,看上去只像是一个静态的类实例,我们为什么可以直接使用request.args 这样的表达式来获取当前request的args属性,而不用使用比如: from flask import get_request
# 获取当前request
request = get_request()
get_request().args
这样的方式呢?flask是怎么把request对应到当前的请求对象的呢?
疑问二 :在真正的生产环境中,同一个工作进程下面可能有很多个线程(又或者是协程), 就像我刚刚所说的,request这个类实例是怎么在这样的环境下正常工作的呢?
要知道其中的秘密,我们只能从flask的源码开始看了。
源码,源码,还是源码
首先我们打开flask的源码,从最开始的__init__.py来看看request是怎么出来的: # File: flask/__init__.py
from .globals import current_app, g, request, session, _request_ctx_stack
# File: flask/globals.py
from functools import partial
from werkzeug.local import LocalStac