HTML发布的表单数据以乱码的形式写入MySQL数据库

时间:2019-05-13 17:34:09

标签: python html bottle

当我尝试在希腊字母的文本字段中输入数据时,我的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">

2 个答案:

答案 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_

然后Read This