> 使用python内置的cgi服务器搭建网站
>
> 网站地址:[ascii-art.lcx-blog.top](http://ascii-art.lcx-blog.top/)
>
> 代码仓库地址:https://github.com/ChenXu-Li/AsciiArtWebsite
**通用网关接口** (英语:Common Gateway Interface,CGI) 是为提供网络服务而执行控制台应用 (或称[命令行界面](https://zh.wikipedia.org/wiki/命令行界面))的程序,提供于服务器上实现[动态网页](https://zh.wikipedia.org/wiki/動態網頁)的通用协议。通常情况下,一次请求对应一个CGI 脚本的执行,生成一个 HTML。[[1\]](https://zh.wikipedia.org/wiki/通用网关接口#cite_note-rfc-3875-1)
简而言之,一个 HTTP POST 请求,从客户端经由 [标准输入](https://zh.wikipedia.org/wiki/标准输入) 发送数据到一个CGI 程序。同时携带其他数据,例如 URL 路径, [HTTP头字段](https://zh.wikipedia.org/wiki/HTTP头字段)数据,被转换为进程的环境变量。
![image-20220905222720135](http://cdn.lcx-blog.top/img/image-20220905222720135.png)
## 简单上手
文件目录结构如下:
```
+---www
| | test_calculater.html
| | test_get.html
| | test_postimg.html
| |
| +---cgi-bin
| | | calculater.py
| | | hello.py
| | | hello_get.py
| | | post_img.py
| |
| |
| \---tmp
| 20120726160810645674.jpg
| 88.jpg
```
1. 先在本机上跑一个hello world,[详情参考](https://zhuanlan.zhihu.com/p/165953436)
在www文件夹下启动python内置服务器
` python -m http.server --cgi 8001`
通过浏览器访问
`http://localhost:8001/cgi-bin/hello.py`
```python
#!/usr/bin/python3
# -*- coding: UTF-8 -*-
import os
import cgitb; cgitb.enable()
print('Content-type:text/html \n\n')
print('Hello CGI~')
print("<meta charset=\"utf-8\">")
print ("<b>环境变量</b><br>")
print ("<ul>")
for key in os.environ.keys():
print ("<li><span style='color:green'>%30s </span> : %s </li>" % (key,os.environ[key]))
print ("</ul>")
```
2. 写个get处理脚本,直接访问能否正常运行
`http://localhost:8001/cgi-bin/hello_get.py?name=hahaha&url=hihihi`
```python
#!/usr/bin/python3
# -*- coding: UTF-8 -*-
# CGI处理模块
import cgi
import cgitb; cgitb.enable()
# 创建 FieldStorage 的实例化
form = cgi.FieldStorage()
# 获取数据
site_name = form.getvalue('name')
site_url = form.getvalue('url')
print ("Content-Type: text/html; charset=utf-8 \n")
print ("<html>")
print ("<head>")
print ("<meta charset=\"UTF-8\">")
print ("<title>菜鸟教程 CGI 测试实例</title>")
print ("</head>")
print ("<body>")
print ("<h2>%s官网:%s</h2>" % (site_name, site_url))
print ("<h2> aaabbb你好 </h2>" )
print ("</body>")
print ("</html>")
```
3. 通过html向服务器发送get
`http://localhost:8001/test_get.html`
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>网站标题</title>
</head>
<body>
<form action="/cgi-bin/hello_get.py" method="get">
站点名称: <input type="text" name="name"> <br />
站点 URL: <input type="text" name="url" />
<input type="submit" value="提交" />
</form>
</body>
</html>
```
4. 实现一个加法器,[详情参考](https://blog.csdn.net/zhyh1435589631/article/details/51530926)
`http://localhost:8001/test_calculater.html`
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>牛马</title>
</head>
<body>
<form action="/cgi-bin/calculater.py" method="get">
数1: <input type="number" name="v1"><br />
数2: <input type="number" name="v2" ><br />
结果: <input type="number" name="re" value="2"><br />
<input type="submit" value="提交" />
</form>
</body>
</html>
```
```python
#!/usr/bin/python
# -*- coding: UTF-8 -*-
# CGI处理模块
import cgi
import cgitb; cgitb.enable()
# 创建 FieldStorage 的实例化
form = cgi.FieldStorage()
# 获取数据
site_v1 = form.getvalue('v1')
site_v2 = form.getvalue('v2')
result = int(site_v1)+int(site_v2)
print(
'''
<!DOCTYPE html>
<html>
<head>
<meta charset=\"utf-8\">
<title>牛马</title>
</head>
<body>
<form action="/cgi-bin/calculater.py" method="get">
数1: <input type="number" name="v1"><br />
数2: <input type="number" name="v2" ><br />
结果: <input type="number" name="re" value="{0}"><br />
<input type="submit" value="提交" />
</form>
</body>
</html>
'''.format(result)
)
```
5. 使用post,试试上传图片,[详情参考](https://www.tutorialspoint.com/python3/python_cgi_programming.htm)
`http://localhost:8001/test_postimg.html`
```html
<html>
<body>
<form enctype = "multipart/form-data" action = "/cgi-bin/post_img.py" method = "post">
<p>File: <input type = "file" name = "filename" /></p>
<p><input type = "submit" value = "Upload" /></p>
</form>
</body>
</html>
```
```python
#!/usr/bin/python3
# -*- coding: UTF-8 -*-
import cgi, os
import cgitb; cgitb.enable()
form = cgi.FieldStorage()
# Get filename here.
fileitem = form['filename']
# Test if the file was uploaded
if fileitem.filename:
fn = os.path.basename(fileitem.filename)
open('tmp/' + fn, 'wb').write(fileitem.file.read())
message = 'The file "' + fn + '" was uploaded successfully'
else:
message = 'No file was uploaded'
print('Content-type:text/html \n\n')#\n\n很重要
print(
'''
<html>
<body>
<p>{0}</p>
</form>
</body>
</html>
'''.format(message)
)
```
简单小网站(一)