论坛首页 Web前端技术论坛

Ajax提交后台需要2次encodeURIComponent?!!

浏览 5714 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-07-01  
最近兄弟刚接手了一个项目,主要维护他的页面浏览器兼容性,里面有一个公司自己的js脚本库,没有使用其他脚本库,以此为背景,很多小问题都顺手解决了。
今天遇到了一个很头痛的问题,在js脚本中发现以下代码
function gb2312Encode(str)
{
	var string = "";
	c = s = "";
	var high = "";
	var low = "";
	for(var i = 0; i < str.length; i++)
	{
	c = Asc(str.charAt(i));
	if(Math.abs(c) < 0xFF)
	   string += str.charAt(i);
	else
	{
	   if(c < 0) c += 0x10000;
	   high = ((c & 0xFF00) >> 8) & 0x00FF;
	   low = c & 0xFF;
	   string += "%" + Hex(high) + "%" + Hex(low);
	}
	}
	return string;
}
function Asc(s)
{
	if (window.navigator.userAgent.indexOf("Firefox") >= 1) {
		return s.charCodeAt(0);
    }
	c = s;
	execScript("c = Asc(c)", "vbscript");
	return c;
	}
function Hex(n)
	{
	c = n;
	execScript("c = Hex(c)", "vbscript");
	return c;
}

一看就知道这是一个牛X写的代码,看gb2312Encode的样子是将一个字符串进行gb2312编码,循环获取每一个字符的ascii编码,如果ascii码绝对值高于255,则计算高地位用%加十六进制进行处理,不过我对字符集编码不懂... Asc 和 Hex使用了只有IE支持的execScript方法,来执行vbscript。

为了减少影响,我不打算动的太多,为了兼容其他浏览器,现只注释现有的Asc和Hex方法,并添加了2个使用javascript的实现。顺手一搜很多个这样的文件,然后在简单的测试后都提交了测试。下面是替换后的代码

/**
 * 将字符转化为Ascii码
 * @param dec
 * @returns
 */
function Asc(dec) {
	return dec.charCodeAt(0);
}
/**
 * 转换10进制为16进制
 * @param dec
 * @returns {String}
 */
function Hex(dec) {
	var hexCode = new Array();
	var i = 0;
	while (dec > 15) {
		hexCode[i] = getHex(dec);
		dec = Math.floor(dec / 16);
		i += 1;
	}
	hexCode[i] = getHex(dec);
	var decToHex = "";
	for (i = hexCode.length - 1; i >= 0; i--) {
		decToHex += hexCode[i];
	}
	return decToHex;
}
function getHex(dec) {
	var hexArray = new Array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9","A", "B", "C", "D", "E", "F");
	var code1 = Math.floor(dec / 16);
	var code2 = dec - code1 * 16;
	var decToHex = hexArray[code2];
	return (decToHex);
}


之后测试就开始给我提Bug了,说有中文有乱码。纠结了很长时间才找到问题的原因 vbscript的Asc 根 javascript的charCodeAt 获得中文ascii码的时候不一致导致的。找了很多资料研究了很长时间发现...这个不是我能解决的,起码不是一会半会能解决的。只好看为么放了这样的一个函数,找到问题的根源,换一种思路解决问题。

	fw.get("other").value = gb2312Encode(fw.get("memoInput").value);


在调用了gb2312Encode之后是一个公司自己的脚本库ajax Post提交后台。后台配置了spring的CharacterEncodingFilter过滤器,项目里面所有的编码统一GBK(文件编码,jsp和html的Content-Type包括jsp的pageEncoding。我也很想用UTF-8啊,我了个擦 java都是GBK的。。工作区都是GBK的。。。很多地方是你们想像不到的。。),过滤器配置也一样。
后台java代码直接从request中取出other,没有在进行转码。  到这里我看明白了,这个牛X是为了处理ajax提交编码的问题。根据我的经验不需要前转码直接用ajax 提交到后台也没问题啊。去掉gb2312Encode调用,纠结的尝试了一把,乱码。

写了个form表单,用表单Post提交没有问题。然后用jquery写了个ajax ,没有问题,写了个很简单的ajax请求,乱码。我了个擦,这是什么情况??

var other1 = encodeURIComponent('团结');
xmlhttp.open("POST", "http://192.168.20.17:8080/hm/hmCreate.php", true);
xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;");
xmlhttp.send("other="+other1);    


上面是自己写的ajax测试,在FF下面看是这个情况 ,第一个请求是自己写的,第2个是用jquery的,后台传递的参数不一样




alert(encodeURIComponent('团结'));// 打印的是 %E5%9B%A2%E7%BB%93


我了个擦,难道是浏览器在提交前有转回去了? 果断又套了层 encodeURIComponent, ajax提交乱码问题解决。感觉很多ajax乱码的问题都是因为这个造成的。。。

xmlhttp.open("POST", "http://192.168.20.17:8080/hm/hmCreate.php", true);
xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;");
xmlhttp.send("other="+encodeURIComponent(encodeURIComponent('团结')));          


为么需要2次encodeURIComponent ? 哪位牛人出来解释解释?
  • 大小: 33.6 KB
   发表时间:2011-07-01  
两侧encodeURIComponent是因为第一次encodeURIComponent的时候出现了"%",这个符号在解析参数的时候是无法解析的,必须把"%"也进行编码,"%"编码后就是"%25",这样就不会出现问题了。
0 请登录后投票
   发表时间:2011-07-01  
两次encodeURIComponent是因为第一次encodeURIComponent的时候出现了"%",这个符号在解析参数的时候是无法解析的,必须把"%"也进行编码,"%"编码后就是"%25",这样就不会出现问题了。
0 请登录后投票
   发表时间:2011-07-02   最后修改:2011-07-02


果然。。
0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics