有运营同学反映,后台编辑的一个中文显示名称,前台乱码了,于是乎~~
先看代码是否get请求没转码:
$.ajax({ type: 'POST',url: '/admin/updatedisplayname}',data: {displayName:displayName},success: function(res){ alert(1); },error: function() { alert(2); },dataType: 'json' })
这段代码不管怎么看,也没有问题,post请求过去的,应该不会存在乱码问题,自己测了下,修改回去了,没乱码(火狐)
奇怪~
问了下,对方用的是谷歌,检查他的浏览器编码有没特殊设置过,没有,一切正常。
纳闷,回来在谷歌测试下,晕死,果然重现,乱码了,哈哈,那就好办,查~
看看请求头信息啥的,发现使用$.ajax请求的时候有一个值有问题
chrome:contentType: 'application/x-www-form-urlencoded'
ff:contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
难道是这个在作祟,如果乎~
$.ajax({ type: 'POST',contentType: 'application/x-www-form-urlencoded; charset=UTF-8',dataType: 'json' })
莫不是有啥玄机,查看jquery手册
contentTypeString
(默认: "application/x-www-form-urlencoded") 发送信息至服务器时内容编码类型。默认值适合大多数情况。如果你明确地传递了一个content-type给 $.ajax() 那么他必定会发送给服务器(即使没有数据要发送)
为毛我在不传入这个值的时候,火狐会加上 charset=UTF-8呢?
看看jquery源码:
ajaxSettings: { url: location.href,global: true,type: "GET",contentType: "application/x-www-form-urlencoded",processData: true,async: true,/* timeout: 0,data: null,username: null,password: null,traditional: false,*/ // Create the request object; Microsoft Failed to properly // implement the XMLHttpRequest in IE7 (can't request local files),// so we use the ActiveXObject when it is available // This function can be overriden by calling jQuery.ajaxSetup xhr: window.XMLHttpRequest && (window.location.protocol !== "file:" || !window.ActiveXObject) ? function() { return new window.XMLHttpRequest(); } : function() { try { return new window.ActiveXObject("Microsoft.XMLHTTP"); } catch(e) {} },accepts: { xml: "application/xml,text/xml",html: "text/html",script: "text/javascript,application/javascript",json: "application/json,text/javascript",text: "text/plain",_default: "*/*" } },
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
果然发现了几个隐藏的bug,不过像这样的直接使用$.ajax一般只有后台系统才用用到,而我们的后台系统是可以不兼容google的,所以当时测试的时候可能没测到。
不过,又有问题,有同学没有加,但是测试是ok的,谷歌不乱码,各种不淡定啊。。。。
再查~
首先想到检查jquery版本,果然,这哥们是用jquery1.7.2,而我用的是1.4.2,查看1.7.2的源码:
ajaxSettings: { url: ajaxLocation,isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),contentType: "application/x-www-form-urlencoded; charset=UTF-8",dataType: null,cache: null,headers: {},*/ accepts: { xml: "application/xml,"*": allTypes },contents: { xml: /xml/,html: /html/,json: /json/ },responseFields: { xml: "responseXML",text: "responseText" },// List of data converters // 1) key format is "source_type destination_type" (a single space in-between) // 2) the catchall symbol "*" can be used for source_type converters: { // Convert anything to text "* text": window.String,// Text to html (true = no transformation) "text html": true,// Evaluate text as a json expression "text json": jQuery.parseJSON,// Parse text as xml "text xml": jQuery.parseXML },// For options that shouldn't be deep extended: // you can add your own custom options here if // and when you create one that shouldn't be // deep extended (see ajaxExtend) flatOptions: { context: true,url: true } },
晕死,在1.7.2中居然加上了charset=UTF-8,
各种~~~~,再探~1.7源码里面也是没有的
好吧,1.7.2里面没有这个问题。
结论:
1、使用1.7.2之前的版本,在使用$.ajax的时候需要自行设置contentType否则,谷歌会乱码。
2、跟浏览器也有关系,火狐就可以自动加上utf-8而谷歌则不会,也行jquery团队发现这个问题,所以就在最新版更正了这个问题。
测试及生成环境:
1、java环境,打包gbk,页面编码gbk,tomcat中URIEncoding配置utf-8等,也许应该跟这些服务器配置也是有关系的,就不深究下去了。
猜测:一般post表单请求的请求数据编码是按照页面里面的Meta指定的编码格式编码的,我们页面是gbk的,所以在谷歌浏览器在未指定ajax的contentType参数的时候采用默认页面编码方式gbk编码然后发送到服务器端,而我们tomcat里面的URIEncoding是utf-8的,所以就两边编码不一样,就乱码了,显式的指定一下就ok。不过貌似ajax统一都是utf-8的来编码的,就算不指定也不会有问题,莫不是谷歌。。。。