概括
这个项目介绍了使用CGI技术通过web服务进行数据流转的方法
准备知识
CGI:通用网关接口,web服务器通过cgi进行数据交互;web服务器通过CGI将数据交给程序(比如本章的filename),并在页面显示结果(html)
web服务器:提供web应用的容器;python -m http.server --cgi便可开启一个web服务器
表单:用来存储传输数据的方法
初次实现
程序获取cgi的参数text;如果存在则保存在将数据保存至simple_edit.dat文件中;并且打印显示出来,保存表单中的文本文件
#!/user/bin/env python
import cgi
form = cgi.FieldStorage()
text = form.getvalue('text',open('D:\pythonCGI\cgi-bin\simple_edit.dat').read())
#用文本的方式读取表单的值
f = open('simple_edit.dat','w')
f.write(text)
f.close()
print("""Content-type:text/html
<html>
<head>
<title>A Simple Editor</title>
</head>
<body>
<form action = 'simple_edit.py' method = 'POST'>
<textarea rows = '10' cols = '20' name = 'text'>
{}
</textarea><br />
<input type = 'submit' />
</from>
</body>
<html>
""".format(text)
)
再次实现
将程序分为三个模块:index.html、edit.py、save.py;
index.html为普通网页提供表单传递文件名给edit.py
edit.py 文本编辑区域;用于输入密码和文本;并且将此通过cgi传递给save.py保存
save.py 验证密码保存输入到指定文件
index.html
<!DOCTYPE html>
<!--刚开始会出错,后面又不会出错,原因未知-->
<html lang="zh_cn">
<head>
<title>File Editor</title>
</head>
<body>
<form action = "edit.py" method = "POST">
<!--表单的声明,点击提交后悔执行edit.py,方法为post,将表单输入的文件名传递给edit.py-->
<b>File name:</b><br /><!--加粗的文字-->
<input type = "text" name = "filename" /> <!--文本输入框,-->
<input type = "submit" value = "Open" /><!--提交按钮输入-->
</form>
</body>
</html>
edit.py
#!/usr/bin/env python
print('Content-type: text/html\n')
from os.path import join, abspath
import cgi, sys
BASE_DIR = abspath('data') #data目录需要方法pythonCGI 下才能被识别出来
form = cgi.FieldStorage()
filename = form.getvalue('filename') #从表单中获取文件名
if not filename:
print('Please enter a file name')
sys.exit()
text = open(join(BASE_DIR, filename)).read()
print("""
<html>
<head>
<title>Editing...</title>
</head>
<body>
<form action='save.py' method='POST'>
<b>File:</b> {}<br /> <!--填入文件名字-->
<input type='hidden' value='{}' name='filename' />
<!--将文件名保存为隐藏表单,传递给下一个页面,同时防止用户修改-->
<b>Password:</b><br />
<input name='password' type='password' /><br /> <!--type设置为password输入显示为*-->
<b>Text:</b><br />
<textarea name='text' cols='40' rows='20'>{}</textarea><br />
<input type='submit' value='Save' />
</form>
</body>
</html>
""".format(filename, filename, text))
save.py
#!/usr/bin/env python
print('Content-type: text/html\n')
from os.path import join, abspath
from hashlib import sha1
import cgi, sys
BASE_DIR = abspath('data')
form = cgi.FieldStorage()
text = form.getvalue('text')
filename = form.getvalue('filename')
password = form.getvalue('password')
if not (filename and text and password):
print('Invalid parameters.')
sys.exit()
if sha1(password.encode()).hexdigest() != '8843d7f92416211de9ebb963ff4ce28125932878':
#这里采用的是安全散列算法,避免密码明文写在代码中,生成的摘要不可能还原为密码
print('Invalid password')
sys.exit()
f = open(join(BASE_DIR,filename), 'w')
f.write(text) #密码正确后数据保存在文档中
f.close()
print('The file has been saved.')
实际测试中发现,windows下启动时访问有时候会报:SError: [WinError 193] %1 不是有效的 Win32 应用程序。
这时用 python -m http.server 启动,再重启后便可正常;且改网页不支持回退操作;原因未知