当我尝试在希腊字母的文本字段中输入数据时,我的wsgi脚本将该数据保存为MySQL数据库中的乱码,我不知道为什么。 这是即将通过表单方法发布数据时的相关代码:
pdata = pdata + '''
<form methods="POST" enctype="multipart/form-data" action="%s">
<tr>
<td> <center> <input type="text" name="task" size=50> </td>
<td> <center> <input type="text" name="price" size=5> </td>
<td> <center> <input type="text" name="lastvisit"> </td>
</table><br><br>
<td> <input type="image" src="/static/img/submit.gif" name="update" value="Ενημέρωση!"> </td>
</tr>
</form>
''' % app.get_url( '/update/<name>', name=name )
pdata = pdata + "<meta http-equiv='REFRESH' content='200;%s'>" % app.get_url( '/' )
return pdata
这是相对的回调函数,试图将发布的表单数据输入到MySQL数据库中。
@app.route( '/update/<name>' )
def update( name ):
pdata = ''
task = request.query.get('task')
price = request.query.get('price')
lastvisit = request.query.get('lastvisit')
# check if date entered as intented, format it properly for MySQL
lastvisit = datetime.strptime(lastvisit, '%d %m %Y').strftime('%Y-%m-%d')
if( ( task and len(task) <= 200 ) and ( price and price.isdigit() and len(price) <= 3 ) and lastvisit != "error" ):
# find the requested client based on its name
cur.execute('''SELECT ID FROM clients WHERE name = %s''', name )
clientID = cur.fetchone()[0]
try:
# found the client, save primary key and use it to issue hits & money UPDATE
cur.execute('''UPDATE clients SET hits = hits + 1, money = money + %s WHERE ID = %s''', ( int(price), clientID ))
# update client profile by adding a new record
cur.execute('''INSERT INTO jobs (clientID, task, price, lastvisit) VALUES (%s, %s, %s, %s)''', ( clientID, task, price, lastvisit ))
except:
cur.rollback()
我不明白为什么数据以乱码而不是正确的utf-8的形式存储到数据库中。另外,尝试使用utf-8编码类型也不起作用。
<form methods="POST" enctype="utf-8" action="%s">
答案 0 :(得分:1)
根据wsgi_mod文档,WSGIDaemonProcess的默认编码为ASCII。希腊字符未包含在ASCII中,并且您的输入未正确解码。如果要允许希腊字符,则必须使用UTF-8或iso-8859-1。通常,服务器是由初始化系统启动的守护程序,并且99%的时间仍然使用ASCII作为默认编码。在进行开发或调试时,通常不会遇到这些问题,因为python脚本继承了通常使用UTF-8的当前用户的环境。
$env
.....
LANG=en_GB.UTF-8
.....
从wsgi_mod引用Apache:
lang =语言环境 设置当前的语言环境。这与设置LANG环境变量相同。 您将需要在许多Linux系统上对此进行设置,其中Apache从系统初始化脚本启动时使用默认的C语言环境,这意味着默认的系统编码为ASCII。除非您需要特殊的语言环境,否则请将其设置为en_US.UTF-8。 lang或locale选项是否工作最佳取决于所使用的系统。如果不确定哪种方法合适,请同时设置两者。
locale =语言环境 设置当前的语言环境。这与设置LC_ALL环境变量相同。 您将需要在许多Linux系统上对此进行设置,其中Apache从系统初始化脚本启动时使用默认的C语言环境,这意味着默认的系统编码为ASCII。除非您需要特殊的语言环境,否则请将其设置为en_US.UTF-8。 lang或locale选项是否工作最佳取决于所使用的系统。如果不确定哪种方法合适,请同时设置两者。
答案 1 :(得分:1)
要发布的html表单数据是“αυτήείναιμιαδοκιμή”,数据库内部的最终结果是“αβαβαβαβαβαβαβ”。
但是,“αυτήείναιμιαδοκιμή”显然是无效的UTF-8,因为
位置38处的字节(ή
)表示它是一个2字节的UTF-8字符,但后面只有1个字节(reference)。
如果完全是 传递给代码的数据;那么您需要检查并确认HTML表单正在以正确的UTF-8格式提交数据。
<form accept-charset='UTF-8'>
假设您的输入字符串正确地采用UTF-8编码,则您的输出字符串“α-β-β-β-β-β-β-β-β”是 UTF-7 或更可能 ISO-8859-1 编码(reference)。
因此,问题可能是传输机制(如上定义;在HTML表单提交中)或数据库存储编码。
是的,MySQL表和列配置为
utf8_general_ci
。
这也可能是一个问题。 MySQL utf8_
不是完整的UTF-8(wat?!),因为它是3字节而不是4字节;因此,如果存储了一个4字节的UTF-8字符,它将偏移所有以后的字符字节,并使它们看起来像垃圾。
将您的MySQL列和所有排序规则更新为utf8mb4_unicode_ci
还要检查并确保您的MySQL传输机制也使用utf8mb4_
。