jQuery: AJAX中的umlauts和特殊字符混乱不堪

5

我刚刚使用jQuery创建了我的第一个ajax函数,它实际上可以工作,但不幸的是字符编码(如ä,ö,ü,ß,č,ć,å,ø)非常困难。

我的文件和数据库都是UTF-8。我尝试了许多选项在ajax函数和PHP函数中,但都不令人满意。

这是我的ajax函数:

var dataString = {
 'name': name,
 'mail': mail
 // other stuff
}


    $.ajax({
type: "POST",
url: "/post.php",
data: dataString,
contentType: "application/x-www-form-urlencoded;charset=UTF-8",
cache: false,
success: function(html){
 // do stuff
}

我已经尝试过不使用contentType: "application/x-www-form-urlencoded;charset=UTF-8",并尝试使用encodeURIComponent()来包装受影响的数据,但这两种方法都没有起作用。

当我在我的php中使用htmlentities()时,我的umlauts在纯文本中看起来像这样: UE Ã�, AE Ã�, OE Ã�, ue ü, ae ä, oe o

在数据库中看起来像这样: UE Ãœ , AE Ä, OE Ö, ue ü, ae ä, oe o

如果我不使用htmlentities()而是使用mysql_real_escape_string()(或者都不用),它们在纯文本中看起来很好,但在数据库中看起来像这样: AE Ä, OE Ö, UE Ãœ, ae ä oe ö ue ü

我已经尝试了很多选项几个小时了,但我找不到一个有效的解决方案。目前,我似乎唯一的选择是让它们在数据库中看起来像一团糟,但如果这些数据集需要被编辑,那将是非常低效的。


1
你最后的观察并不是暗示问题出在 jQuery 和 AJAX 上,而更可能是数据库(或许还有 PHP)的问题,对吧? - Konrad Rudolph
我尝试将数据库编码更改为latin1,但没有任何区别。 - rayne
4个回答

6
我试过将受影响的数据用encodeURIComponent()包装起来。
如果你传入一个{}对象,jQuery会为你处理UTF-8和URL编码。
当我在我的php中使用htmlentities()进行AJAX调用时,我的变音字母看起来像这样的纯文本:UE Ã�, AE Ã�, OE Ã�, ue ü, ae ä, oe o。
如果你必须使用htmlentities(),你必须在可选的$charset参数中告诉它你的编码是UTF-8,否则它会(愚蠢地)默认将所有字节视为ISO-8859-1,并为每个字节编码为不适当的实体引用。
更好的方法是使用htmlspecialchars(),因为它不会尝试对除了那些真正需要它的少数ASCII字符以外的字符应用不必要的编码。
你是如何确定的?你用来获取数据库数据的工具是否了解Unicode?(如果它是一个不靠谱的PHP网络管理界面,也许不行。PHP在Unicode方面做得不太好。)
有可能你在数据库中存储了正确的UTF-8字节,但在标记为Latin-1排序规则的表中。这样做是可以的,只要你能得到相同的字节,但如果MySQL不知道它们是UTF-8字节,则超出ASCII范围的不区分大小写的字符串比较将无法正常工作,因此寻找Ä将不会匹配ä。这可能或可能不重要。
谨慎一点。HTML转义是用于输出到页面的阶段。SQL字符串文字转义发生在创建SQL查询时。你需要它们两个,但不要混淆它们或尝试在同一阶段完成它们,否则你将拥有各种奇怪的逃避错误和潜在的漏洞。

当我使用htmlspecialchars()时,字符在网站上看起来很好,但在数据库中却像这样:ü(无论数据库是UTF-8还是latin1)。我使用SQLyog访问数据库,我没有像phpmyadmin那样的Web界面。当我使用自定义构建的管理界面编辑它们时,它们也看起来很混乱。 - rayne
好的,SQLyog声称支持Unicode,所以希望它能做得正确。如果你很在意在管理界面中数据的显示效果,那么你需要使用CREATE TABLE ... CHARACTER SET utf8来创建表,并在使用数据库连接之前从PHP调用mysql_set_charset('utf8') - bobince

3

听起来问题出现在将数据插入数据库时。您使用的是MySQL吗?连接到数据库服务器后,发出以下查询:

SET NAMES utf8;

这将告诉数据库服务器客户端连接希望以UTF-8格式发送数据,并按照该格式进行解释。

此外,在将此数据发送到浏览器时,请确保设置ContentType头。

header('Content-type: text/html; charset=utf-8');

这将告诉浏览器将数据解释为UTF-8格式。

1

尝试使用这个函数而不是htmlentities

htmlspecialchars()


0

我终于找到了适合我的解决方案;我从我的jQuery ajax中删除contentType: "application/x-www-form-urlencoded;charset=UTF-8",我只使用htmlentities($value, ENT_NOQUOTES, 'UTF-8');来处理SQL数据,我的数据库设置为utf8 unicode。

字符正确显示,并以ä等形式存储在数据库中。


请不要将HTML编码的数据存储在数据库中! HTML转义是一个输出问题,应该始终只在页面输出阶段进行。它不属于数据访问层。如果您将HTML编码的数据放入数据库中,则无法执行像LIKE'%uml%'这样的搜索(它无法区分编码的变音符号和文本“uml”之间的区别),每个SUBSTRING操作(包括由于字段长度限制而导致的隐式修剪)都会破坏实体引用并生成损坏的HTML,并且它会破坏表数据的任何非HTML使用,例如发送邮件。 - bobince
哦,真的吗?我不知道,但总体来说我是个糟糕的程序员 ;)当我从脚本中删除htmlentities()时,我的特殊字符在数据库中看起来像这样:ü奇怪的是,当我只通过PHP发送数据(禁用javascript时),它们在数据库中看起来很好(ä)。因此,问题很可能是由jQuery ajax引起的。 - rayne

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接