知其然,知其所以然
Flask 内部机制 2026-10-02

上传文件大小限制

实测 MAX_CONTENT_LENGTH:默认不限制;超限返回 413;只在读请求体时才检查;Flask 3.1 可按请求设 request.max_content_length;真实 gunicorn + curl 上传 30 MB 在限制 1 MB 时很快返回 413(只发出一部分);chunked 上传在本机实测里被截断到限制大小却返回 200。

Flask 上传大小限制 MAX_CONTENT_LENGTH 413 真实验证 动画演示
Flask 内部机制 2026-10-02

secure_filename() 的安全处理

实测 secure_filename:30 种输入的结果;中文文件名被整个去掉;不清洗直接拼路径会写到上传目录之外;20030 个输入的模糊测试越界 0 个;白名单 + 随机文件名的组合;safe_join。本机上 CON 等 Windows 保留名不被改动,长度也不限制。

Flask secure_filename 文件上传安全 路径穿越 真实验证 动画演示
Flask 内部机制 2026-10-02

Response 对象构造过程

实测 Response 对象的构造:response/status/headers/mimetype/content_type 的相互影响(mimetype 自动补 charset、content_type 原样);status 与 status_code 同步且不校验范围;Headers 不区分大小写可重复;换行符被拒;set_data 更新 Content-Length;作为 WSGI 可调用对象的最终输出。

Flask Response 响应对象 headers 真实验证 动画演示
Flask 内部机制 2026-10-02

JSON Response 的序列化

实测 jsonify 与 Flask 的 JSON provider:默认排序键且 ensure_ascii=True(中文变 \uXXXX);debug 时缩进;datetime/UUID/Decimal/dataclass 能序列化,set/bytes/Enum/普通对象不行;NaN 原样输出;自定义 provider;return dict 与 jsonify 相同;排序键比不排序慢约 31%。

Flask JSON jsonify 序列化 真实验证 动画演示
Flask 内部机制 2026-10-02

自定义 Response Class

实测自定义 Response 类:response_class 能统一加头、改 default_mimetype(但会把字符串也标成 JSON);force_type 只处理 Response 与 WSGI callable,无法让视图直接返回模型对象;重写 Flask.make_response 才行;default_mimetype 与 mimetype、content_type 的关系。

Flask Response response_class make_response 真实验证 动画演示
Flask 内部机制 2026-10-02

Streaming Response

用真实 gunicorn 验证流式响应:生成器返回 chunked、第一块立刻到达(对比拼好再返回要等 1.02 秒);线路上的分块格式;stream_with_context 保住请求上下文;300 MB 响应流式峰值内存约 38 MiB、一次性约 338 MiB;客户端断开时生成器的 finally 会执行。

Flask 流式响应 stream_with_context chunked 真实验证 动画演示
Flask 内部机制 2026-10-02

send_file() 与 send_from_directory()

实测 send_file 与 send_from_directory:响应头(ETag、Last-Modified、no-cache、Content-Disposition 与 filename*=);BytesIO 必须给 mimetype 或 download_name;max_age/etag/conditional;穿越返回 404;send_file 找不到文件是 500 而 send_from_directory 是 404;USE_X_SENDFILE;300 MB 下载峰值内存约 35 MiB 对 335 MiB。

Flask send_file send_from_directory 文件下载 真实验证 动画演示
Flask 内部机制 2026-10-02

ETag 与条件请求

实测 ETag 与条件请求:add_etag 用正文 SHA-1、If-None-Match 命中返回 304 无正文;弱 ETag 的弱比较;手写 ETag 先判断后生成;If-Match 返回 412 防止丢失更新;304 省的是流量(58890 字节 → 0),不是服务器计算(200 与 304 都约 465 µs)。

Flask ETag 条件请求 304 真实验证 动画演示
Flask 内部机制 2026-10-02

Last-Modified 与缓存响应

实测 Last-Modified 与 If-Modified-Since(秒级精度、非法值被忽略、If-None-Match 优先于它);Cache-Control 各指令的写法;Expires;访问 session 会自动加 Vary: Cookie;响应带登录态时要自己加 private 或 no-store。

Flask Last-Modified Cache-Control 缓存 Vary 真实验证 动画演示
Flask 内部机制 2026-10-02

Cookie 的读写过程

实测 Flask 的 cookie 读写:set_cookie 各参数的 Set-Cookie 形式;delete_cookie 要同 path;请求 Cookie 头的解析(重复名取第一个、百分号不解码、名字含空格被丢弃);中文值的八进制转义往返;MAX_COOKIE_SIZE 4093 只是警告;samesite 取值与 Partitioned。

Flask Cookie set_cookie SameSite 真实验证 动画演示
Flask 内部机制 2026-10-02

Signed Cookie

用 itsdangerous 验证签名 cookie:payload.timestamp.signature 三段,payload 明文可读;手工按 sha1 派生密钥 + HMAC-SHA1 算出一致的签名;改任何一处、换密钥或 salt 都验证失败;max_age 过期;Flask 里做「记住我」cookie;没有撤销;压缩与大小开销。

Flask 签名 Cookie itsdangerous HMAC 真实验证 动画演示
Flask 内部机制 2026-10-02

Session Cookie 的数据结构

解开 Flask session cookie:payload.timestamp.signature 三段,payload 不需要密钥就能读;TaggedJSON 对 bytes/datetime/tuple/UUID/Markup 的标记;permanent 才有 Expires;什么时候重发 Set-Cookie;超过 4093 字节警告;篡改后静默得到空 session;salt=cookie-session、key_derivation=hmac。

Flask Session Cookie 签名 真实验证 动画演示
京ICP备2026067502号-1京公网安备11010502063487号