Python3 CGI编程
How CGI worked, why nobody uses it in production, and what replaced it.
Key PointsCGI starts a new process per request — that is why it is dead; the cgi module was removed in Python 3.13, use WSGI/ASGI instead.
How CGI Worked
The web server forked a new Python process for every request, passed the request in environment variables and stdin, and read the response from stdout. Simple to implement, ruinous at scale.
Python
#!/usr/bin/env python3
# legacy CGI script: the server runs this once per request
import os
import sys
length = int(os.environ.get("CONTENT_LENGTH") or 0)
body = sys.stdin.read(length)
print("Content-Type: text/plain; charset=utf-8")
print()
print(f"method={os.environ.get('REQUEST_METHOD')} body={body}")Why It Died
| Problem | Impact |
|---|---|
| Process per request | ~10-50 ms startup each time |
| No connection reuse | Database connections opened per request |
| No in-process state | No caches, no pools, no sessions |
| Hard to deploy | CGI directory permissions, shebang perms |
What Replaced It
- WSGI (PEP 3333): a long-lived process handles many requests — Flask, Django.
- ASGI: the async successor — FastAPI, Starlette.
- FastCGI / uWSGI: persistent processes behind nginx.
import cgi fails on Python 3.13+. If you maintain legacy code, migrate to WSGI — there is no drop-in replacement for the cgi module.CGI 的工作方式
Web 服务器为每个请求 fork 一个新的 Python 进程,通过环境变量和 stdin 传入请求,从 stdout 读取响应。实现极简,扩展性极差。
Python
#!/usr/bin/env python3
# legacy CGI script: the server runs this once per request
import os
import sys
length = int(os.environ.get("CONTENT_LENGTH") or 0)
body = sys.stdin.read(length)
print("Content-Type: text/plain; charset=utf-8")
print()
print(f"method={os.environ.get('REQUEST_METHOD')} body={body}")为什么被淘汰
| 问题 | 影响 |
|---|---|
| 每请求一个进程 | 每次 10~50 毫秒启动开销 |
| 无法复用连接 | 每请求新建数据库连接 |
| 无法保存进程内状态 | 没有缓存、连接池、会话 |
| 部署困难 | CGI 目录权限、脚本权限 |
取代它的方案
- WSGI(PEP 3333):常驻进程处理多个请求 —— Flask、Django。
- ASGI:异步后继者 —— FastAPI、Starlette。
- FastCGI / uWSGI:挂在 nginx 后面的常驻进程。
Python 3.13+ 里
import cgi 会直接失败。维护老代码请迁到 WSGI —— cgi 模块没有等价替代品。