Mysql 在保存用户输入之前,如何清理用户输入以进行正确的内容编码?

Mysql 在保存用户输入之前,如何清理用户输入以进行正确的内容编码?,mysql,perl,encoding,user-input,Mysql,Perl,Encoding,User Input,我有一个应用程序,用户可以在表单中输入文本 数据保存到MySQL数据库中(排序规则:utf8\u general\u ci),然后作为XML输出(编码:UTF-8) 问题是人们倾向于剪切和粘贴来自其他来源的信息,例如Microsoft Word文档或PDF 此输入文本通常具有不适合输出编码的字符,如“智能引号”,这些字符来自中的文档 显然,这会在转换或处理XML时产生问题,因为字符是非法的 那么,如何对输入进行消毒 在此之前,我使用了一些相当暴力的方法,比如由一长串搜索和替换操作组成的 这仍然是

我有一个应用程序,用户可以在表单中输入文本

数据保存到MySQL数据库中(排序规则:
utf8\u general\u ci
),然后作为XML输出(编码:UTF-8)

问题是人们倾向于剪切和粘贴来自其他来源的信息,例如Microsoft Word文档或PDF

此输入文本通常具有不适合输出编码的字符,如“智能引号”,这些字符来自中的文档

显然,这会在转换或处理XML时产生问题,因为字符是非法的

那么,如何对输入进行消毒

在此之前,我使用了一些相当暴力的方法,比如由一长串搜索和替换操作组成的

这仍然是最好的方法吗?还有别的办法吗

我可以在表单上设置并让浏览器为我执行吗

如果是的话,哪些浏览器会这样做?可能会有什么问题吗

还有,为什么我的数据库接受这些字符,它们是UTF-8中的保留/控制字符

正如你所看到的,我对编码的了解足以让我知道我有问题,但我现在有点不知所措

TIA

您可以尝试Perl模块。它支持多个字符集之间的转换,包括couse的UTF-8。我刚刚检查了Perl的安装,它还支持“cp1252”,根据维基百科,这只是Windows-1252的另一个名称。您可以使用以下一个衬里检查自己的安装:

perl -MEncode -e 'print map {"$_\n"} Encode->encodings(":all");'
此输入文本通常包含不适合输出编码的字符,例如“智能引号”,它们来自Windows-1252编码的文档

“智能引号”(cp1252中的字节147和148)是完全有效的Unicode字符U+201C和U+201D。您的应用程序应该能够无缝地处理它们;如果没有,您就做错了,很可能所有非ASCII字符都会失败

无论字符是来自键入字符的人还是从Word粘贴字符的人,浏览器都应该向应用程序提交UTF-8编码的字符,应用程序应该将相同的UTF-8字节存储到数据库中

如果浏览器未使用UTF-8提交,则很可能是您未能设置包含表单的HTML页面的字符集。这可以通过以下方式完成:

Content-Type: text/html;charset=utf-8
HTTP头和/或:

<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />

加入元素


我可以在表单上设置accept charset属性并让浏览器帮我完成吗

不,由于IE,accept字符集基本上是无用的,IE将其误解为“如果页面上的字符不能编码我们想要的字符,请尝试使用此字符集”,而不是“始终使用此字符集”。这意味着,如果使用accept字符集,最终可能会同时提交混合编码,而无法确定哪个是哪个。很好

为什么我的数据库接受这些字符,它们是UTF-8中的保留/控制字符

在MySQL中,UTF-8只是一个排序规则,用于比较和排序。它仍然将数据存储为字节,并不真正关心它们是否是无效的UTF-8序列

在应用程序中解码和检查传入的UTF-8序列是个好主意,因为在现代Unicode中无效的“短序列”可以隐藏一个“”我可以在表单上设置accept charset属性并让浏览器为我执行吗

只有当你准备好信任“浏览器”——这可能适用于某些应用程序,但总的来说,这会让你自己很容易受到伤害(甚至更糟)

(另请参见bobince关于IE的警告…)


Iain

OK“字节147和148是完全有效的Unicode字符,U+201C和U+201D”是我不知道的部分。浏览器无法知道粘贴测试的编码。它怎么知道它们是CP1252智能报价?当然,它们只是字节!或者147-148的使用是如此不同寻常,以至于可以安全地假设?浏览器不处理字节,而是处理Unicode字符。将Unicode字符U+201C(等)粘贴到文本区域;浏览器既不知道也不关心它们是如何存储在您从中复制出来的应用程序中的(可能是Unicode)。它可能会提交字节147/148,但这可能是因为它认为包含表单的页面的编码是cp1252,因此表单希望获得的编码是cp1252。如果你不告诉它,它可以默认为cp1252(或其他国家的其他系统代码页)。如果我从Word中剪切一个包含字节147的字符串,然后将其粘贴到浏览器的输入字段中,你说浏览器会做什么?自动将其转换为U+201C,因为它“知道”这是一个智能报价,并且它有一个内部1252-UTF8映射?顺便说一下,页面的编码是UTF-8。我可能能够追踪到实际用户,让他们告诉我他们是如何准确输入文本的,因为这是一个内部应用程序。