Python3 CGI编程¶
概念与用途¶
CGI 让 Web 服务器为每个请求启动程序,并通过环境变量、标准输入输出交换 HTTP 数据。它有助于理解 HTTP 响应,但进程开销大,现代项目应采用 WSGI/ASGI 框架。标准库 cgi 在 Python 3.10 仍可用、3.11 起依照 PEP 594 弃用、3.12 是最后包含它的版本,并在 Python 3.13 移除;本页示例刻意不依赖该模块。
核心协议¶
程序必须先输出响应头、空行,再输出正文。请求方法、查询串和内容长度来自 REQUEST_METHOD、QUERY_STRING、CONTENT_LENGTH 等环境变量。
| 输入/输出 | 来源 | 处理要求 |
|---|---|---|
| 查询参数 | QUERY_STRING |
URL 解码、长度和字段白名单 |
| 请求正文 | 标准输入 | 按 CONTENT_LENGTH 限量读取 |
| 响应头 | 标准输出首部 | 每行合法,之后输出空行 |
| 响应正文 | 标准输出 | 与声明的 Content-Type 一致 |
#!/usr/bin/env python3
import html
import os
from urllib.parse import parse_qs
params = parse_qs(os.environ.get("QUERY_STRING", ""))
name = html.escape(params.get("name", ["访客"])[0])
print("Content-Type: text/html; charset=utf-8")
print()
print(f"<h1>Hello, {name}</h1>")
示例:生成 JSON 响应¶
下面示例可直接运行,它展示 CGI 响应格式而不要求 Web 服务器。部署时服务器负责设置环境变量并执行脚本。
#!/usr/bin/env python3
import json
import os
payload = {
"method": os.environ.get("REQUEST_METHOD", "GET"),
"status": "ok",
}
body = json.dumps(payload, ensure_ascii=False)
print("Status: 200 OK")
print("Content-Type: application/json; charset=utf-8")
print(f"Content-Length: {len(body.encode('utf-8'))}")
print()
print(body)
CGI 脚本还依赖服务器执行权限、shebang、工作目录和超时配置。上传文件与 multipart 解析不应自行草率实现;遗留系统若仍依赖已移除的 cgi,应固定受支持运行环境或迁移到维护中的框架/第三方替代,而不是复制旧模块代码。
常见错误与安全注意¶
- 输出 HTML 前必须转义用户输入,并对参数长度、类型和数量设限。
- 不要把异常堆栈、环境变量或服务器路径返回客户端。
- CGI 是遗留部署方式;新系统优先 Flask、Django、FastAPI 等受维护方案。
- 请求体读取必须设置上限,脚本执行应使用低权限账户并由服务器限制运行时间。