详解cgi向文本或者数据库写入数据实例代码
《详解CGI向文本或者数据库写入数据实例代码》
在Web开发中,CGI(Common Gateway Interface)作为早期动态网页交互的核心技术,至今仍广泛应用于轻量级Web服务场景。本文将系统讲解如何通过Python CGI脚本实现向文本文件或数据库写入数据的完整流程,涵盖基础环境配置、文件操作、数据库连接及安全实践,并提供可运行的实例代码。
一、CGI基础与环境配置
CGI通过标准输入/输出与Web服务器交互,要求脚本具有可执行权限并放置在服务器CGI目录(如Apache的cgi-bin)。以下以Apache为例说明配置步骤:
# 1. 启用Apache的CGI模块
sudo a2enmod cgi
# 2. 修改配置文件(/etc/apache2/sites-available/000-default.conf)
Options +ExecCGI
AddHandler cgi-script .py
Require all granted
# 3. 重启Apache
sudo systemctl restart apache2
Python CGI脚本需包含以下标准结构:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import cgi
import cgitb
# 启用错误追踪(生产环境应关闭)
cgitb.enable()
# 设置HTTP响应头
print("Content-Type: text/html;charset=utf-8")
print() # 空行分隔头部与内容
# 业务逻辑...
二、向文本文件写入数据
文本文件写入是CGI最简单的数据持久化方式,适用于日志记录、简单配置等场景。需注意文件路径权限和并发写入问题。
1. 基础写入示例
#!/usr/bin/env python3
import cgi
import cgitb
cgitb.enable()
print("Content-Type: text/html")
print()
# 获取表单数据
form = cgi.FieldStorage()
user_input = form.getvalue('content', '')
# 写入文件(追加模式)
try:
with open('/var/www/data/user_data.txt', 'a') as f:
f.write(f"{user_input}\n")
print("数据写入成功")
except Exception as e:
print(f"写入失败: {str(e)}")
HTML表单示例:
2. 高级处理技巧
(1)文件锁定机制(解决并发写入冲突):
import fcntl
def safe_write(filename, content):
with open(filename, 'a') as f:
fcntl.flock(f, fcntl.LOCK_EX) # 获取独占锁
f.write(content + '\n')
fcntl.flock(f, fcntl.LOCK_UN) # 释放锁
(2)JSON格式存储:
import json
data = {"timestamp": "2023-01-01", "content": user_input}
with open('data.json', 'a') as f:
json.dump(data, f)
f.write('\n') # 每条记录一行
三、向数据库写入数据
对于结构化数据,数据库是更可靠的选择。本文以MySQL和SQLite为例演示操作。
1. MySQL数据库操作
(1)安装依赖:
sudo apt install python3-mysql.connector
(2)完整写入示例:
#!/usr/bin/env python3
import cgi
import cgitb
import mysql.connector
from mysql.connector import Error
cgitb.enable()
print("Content-Type: text/html")
print()
def create_connection():
try:
return mysql.connector.connect(
host='localhost',
user='cgi_user',
password='secure_password',
database='cgi_db'
)
except Error as e:
print(f"数据库连接失败: {e}")
return None
form = cgi.FieldStorage()
name = form.getvalue('name', '')
email = form.getvalue('email', '')
conn = create_connection()
if conn:
try:
cursor = conn.cursor()
sql = "INSERT INTO users (name, email) VALUES (%s, %s)"
cursor.execute(sql, (name, email))
conn.commit()
print("用户信息保存成功")
except Error as e:
print(f"数据库错误: {e}")
finally:
conn.close()
2. SQLite轻量级方案
SQLite无需服务器,适合小型应用:
#!/usr/bin/env python3
import cgi
import cgitb
import sqlite3
from sqlite3 import Error
cgitb.enable()
print("Content-Type: text/html")
print()
def create_connection(db_file):
try:
return sqlite3.connect(db_file)
except Error as e:
print(f"连接失败: {e}")
return None
form = cgi.FieldStorage()
task = form.getvalue('task', '')
conn = create_connection('todo.db')
if conn:
try:
cursor = conn.cursor()
cursor.execute('''CREATE TABLE IF NOT EXISTS tasks
(id INTEGER PRIMARY KEY AUTOINCREMENT,
task TEXT NOT NULL)''')
cursor.execute("INSERT INTO tasks (task) VALUES (?)", (task,))
conn.commit()
print("任务添加成功")
except Error as e:
print(f"数据库错误: {e}")
finally:
conn.close()
四、安全实践与优化
1. 输入验证与净化:
import re
def sanitize_input(input_str):
# 移除HTML标签
clean = re.compile('<.>')
input_str = re.sub(clean, '', input_str)
# 限制长度
return input_str[:200] if input_str else ''
2. 防止SQL注入:
- 始终使用参数化查询(如MySQL的%s占位符)
- 避免直接拼接SQL字符串
3. 错误处理最佳实践:
try:
# 数据库操作
except mysql.connector.Error as err:
if err.errno == mysql.connector.errorcode.ER_ACCESS_DENIED_ERROR:
print("数据库认证失败")
elif err.errno == mysql.connector.errorcode.ER_BAD_DB_ERROR:
print("数据库不存在")
else:
print(f"未知错误: {err}")
五、完整项目示例:留言板系统
结合文本存储和数据库的混合方案:
#!/usr/bin/env python3
import cgi
import cgitb
import sqlite3
import json
from datetime import datetime
cgitb.enable()
print("Content-Type: application/json")
print()
def init_db():
conn = sqlite3.connect('messages.db')
c = conn.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS messages
(id INTEGER PRIMARY KEY AUTOINCREMENT,
content TEXT NOT NULL,
timestamp DATETIME)''')
conn.commit()
conn.close()
def save_to_db(content):
conn = sqlite3.connect('messages.db')
c = conn.cursor()
c.execute("INSERT INTO messages (content, timestamp) VALUES (?, ?)",
(content, datetime.now().isoformat()))
conn.commit()
conn.close()
def save_to_file(content):
with open('messages.log', 'a') as f:
f.write(json.dumps({
'content': content,
'timestamp': datetime.now().isoformat()
}) + '\n')
form = cgi.FieldStorage()
message = form.getvalue('message', '').strip()[:500]
if message:
init_db()
save_to_db(message)
save_to_file(message)
print(json.dumps({'status': 'success'}))
else:
print(json.dumps({'status': 'error', 'message': '空内容'}))
六、部署与测试要点
1. 文件权限设置:
sudo chown -R www-data:www-data /var/www/cgi-bin/
sudo chmod 755 /var/www/cgi-bin/*.py
2. 测试方法:
- 使用curl命令测试:
curl -X POST -d "content=测试数据" http://localhost/cgi-bin/script.py
- 浏览器开发者工具查看网络请求
3. 日志记录:
import logging
logging.basicConfig(
filename='/var/log/cgi_app.log',
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
try:
# 业务逻辑
except Exception as e:
logging.error(f"处理请求时出错: {str(e)}", exc_info=True)
关键词:CGI编程、Python文件操作、MySQL数据库、SQLite数据库、Web数据持久化、输入验证、SQL注入防护、并发写入处理
简介:本文详细介绍Python CGI脚本实现文本文件和数据库写入的技术方案,涵盖基础环境配置、文件操作技巧、MySQL/SQLite数据库连接、安全防护措施及完整项目示例,适合Web开发初学者和需要轻量级数据存储的场景。