请求进来之后,request 为什么能在任何地方被直接读到?请求上下文什么时候建立、里面有什么、能不能带进线程?这篇用 test_request_context 把它拆开看。
request.path → RuntimeError: Working outside of request context. This typically means that you attempted to use functionality that needed an active HTTP request. Consult the documentation on testing for information about how to avoid this problem. session → RuntimeError: Working outside of request context. This typically means that you attempted to use functionality that needed an active HTTP request. Consult the documentation on testing for information about how to avoid this problem.
上一篇:Flask Application Context;下一篇:current_app、request、g 的实现。
源码:
1 | with app.test_request_context('/a/b?x=1&y=2', method='POST', data={'k': 'v'}, headers={'X-T': '1'}):
2 | print(request.method, request.path, dict(request.args), dict(request.form), request.headers['X-T'])
3 | print([k for k in request.environ if k.isupper()][:8], len(request.environ))
POST /a/b {'x': '1', 'y': '2'} {'k': 'v'} 1
environ 里的大写键: ['REQUEST_METHOD', 'SCRIPT_NAME', 'PATH_INFO', 'QUERY_STRING', 'REQUEST_URI', 'RAW_URI', 'SERVER_NAME', 'SERVER_PORT', 'HTTP_HOST', 'SERVER_PROTOCOL', 'CONTENT_TYPE', 'CONTENT_LENGTH', 'HTTP_X_T']
environ 里 wsgi.* 键: ['wsgi.version', 'wsgi.url_scheme', 'wsgi.input', 'wsgi.errors', 'wsgi.multithread', 'wsgi.multiprocess', 'wsgi.run_once'] push 之前 has_app_context / has_request_context: False False | ctx.url_adapter 类型: MapAdapter
push 之前读 ctx.session → AssertionError: The session has not yet been opened.
push 之后: True True | request.url_rule = /user/<int:uid> | view_args = {'uid': 42} | session 类型 = SecureCookieSession
pop 之后: False Falsepush 成功;request.url_rule = None | routing_exception = <NotFound '404: Not Found'> dispatch_request() 才抛出: NotFound - 404 Not Found: The requested URL was not found on the server. If you entered the
session 类型: NullSession | session.get("a") = None
写入 → The session is unavailable because no secret key was set. Set the secret_key on the application to something unique and secret.
配了 SECRET_KEY 后: SecureCookieSession {'a': 1}裸线程: RuntimeError: Working outside of request context. This typically means th copy_current_request_context: / (线程里读到)
响应返回之后仍可访问:request.path = /set | request.args = {'x': '1'} | session = {'u': 'ann'}
with 块之后 has_request_context = False_cv_app = <ContextVar name='flask.app_ctx' at 0x109d85260> | _cv_request = <ContextVar name='flask.request_ctx' at 0x10a866c50> 请求之外 _cv_request.get(None) = None 请求内 _cv_request.get() 的类型: flask.ctx.RequestContext | ctx.app.name = x | ctx.request 类型: Request