在 Python 中,要实现类似 PHP 的“请求哪个脚本就执行哪个脚本”的动态 HTTP 脚本执行机制,有几种方式可以做到。以下是一个完整的实现思路(核心思想:解析 URL 路径,根据路径动态加载并执行对应的 Python 脚本文件):
示例目标:
当访问 http://localhost:8000/hello.py,服务器执行 hello.py 并返回它的输出内容(如同 PHP 一样)。
实现方法:用 http.server + 动态加载执行
# dynamic_http_server.py import os import sys import io import traceback from http.server import SimpleHTTPRequestHandler, HTTPServer from urllib.parse import unquote class DynamicScriptHandler(SimpleHTTPRequestHandler): def do_GET(self): path = unquote(self.path.lstrip('/')) # 只处理 .py 脚本文件请求 if path.endswith(".py") and os.path.isfile(path): try: # 用独立的 namespace 执行脚本 stdout = io.StringIO() sys.stdout = stdout script_globals = {"__name__": "__main__"} with open(path, 'r', encoding='utf-8') as f: code = f.read() exec(code, script_globals) output = stdout.getvalue() sys.stdout = sys.__stdout__ # 返回结果 self.send_response(200) self.send_header("Content-type", "text/plain; charset=utf-8") self.end_headers() self.wfile.write(output.encode('utf-8')) except Exception as e: sys.stdout = sys.__stdout__ self.send_response(500) self.end_headers() self.wfile.write(f"Error executing {path}:\n{traceback.format_exc()}".encode('utf-8')) else: # 默认静态文件处理 super().do_GET() if __name__ == '__main__': port = 8000 print(f"Serving on http://localhost:{port}/") httpd = HTTPServer(('', port), DynamicScriptHandler) httpd.serve_forever()
示例 hello.py 脚本:
print("Hello from Python script!")
运行方式:
python dynamic_http_server.py
然后访问:
http://localhost:8000/hello.py
补充说明:
动态脚本解析 | ✅(像 PHP 一样执行 .py 脚本) |
脚本输出到前端 | ✅(print 输出将返回给浏览器) |
安全性 | ⚠️ 极低(不建议在公网使用,容易被任意执行命令) |
POST/参数支持 | ❌ 默认不支持(可扩展) |
如果你想做成类似 PHP-CGI 的生产用法(推荐):
考虑用:
FastAPI + exec() 动态执行脚本;
uWSGI or Gunicorn + 定制化调度逻辑;
自定义 sandbox 环境(限制导入模块、输出内容等);
如你有安全考虑或想支持 POST 参数,也可以告诉我,我可以升级这个架构支持完整的 GET/POST 参数解析、路径路由转发、沙箱执行 等功能。是否需要?
网友回复