职业IT人-IT人生活圈

 找回密码
 成为会员
搜索
查看: 646|回复: 3

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

[复制链接]
曾经的小孩 发表于 2011-8-28 09:44 | 显示全部楼层 |阅读模式
最近兄弟刚接手了一个......
两侧encodeUR......
两次encodeUR......
果然。。......


最近兄弟刚接手了一个项目,主要维护他的页面浏览器兼容性,里面有一个公司自己的js脚本库,没有使用其他脚本库,以此为背景,很多小问题都顺手解决了。
今天遇到了一个很头痛的问题,在js脚本中发现以下代码
Java代码  
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;   
}  

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的实现。顺手一搜很多个这样的文件,然后在简单的测试后都提交了测试。下面是替换后的代码

Java代码  
/**  
* 将字符转化为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 = getHex(dec);   
        dec = Math.floor(dec / 16);   
        i += 1;   
    }   
    hexCode = getHex(dec);   
    var decToHex = "";   
    for (i = hexCode.length - 1; i >= 0; i--) {   
        decToHex += hexCode;   
    }   
    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);   
}  

/**
* 将字符转化为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 = getHex(dec);
                dec = Math.floor(dec / 16);
                i += 1;
        }
        hexCode = getHex(dec);
        var decToHex = "";
        for (i = hexCode.length - 1; i >= 0; i--) {
                decToHex += hexCode;
        }
        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码的时候不一致导致的。找了很多资料研究了很长时间发现...这个不是我能解决的,起码不是一会半会能解决的。只好看为么放了这样的一个函数,找到问题的根源,换一种思路解决问题。

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

        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请求,乱码。我了个擦,这是什么情况??

Java代码  
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);      

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的,后台传递的参数不一样




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

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


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

Java代码  
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('团结')));            

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-8-28 09:45 | 显示全部楼层
两侧encodeURIComponent是因为第一次encodeURIComponent的时候出现了"%",这个符号在解析参数的时候是无法解析的,必须把"%"也进行编码,"%"编码后就是"%25",这样就不会出现问题了。

木已 发表于 2011-8-28 09:45 | 显示全部楼层
两次encodeURIComponent是因为第一次encodeURIComponent的时候出现了"%",这个符号在解析参数的时候是无法解析的,必须把"%"也进行编码,"%"编码后就是"%25",这样就不会出现问题了。

走就走吧 发表于 2011-8-28 09:45 | 显示全部楼层


果然。。
您需要登录后才可以回帖 登录 | 成为会员

本版积分规则

QQ|手机版|小黑屋|网站帮助|职业IT人-IT人生活圈 ( 粤ICP备12053935号-1 )|网站地图
本站文章版权归原发布者及原出处所有。内容为作者个人观点,并不代表本站赞同其观点和对其真实性负责,本站只提供参考并不构成任何投资及应用建议。本站是信息平台,网站上部分文章为转载,并不用于任何商业目的,我们已经尽可能的对作者和来源进行了通告,但是能力有限或疏忽造成漏登,请及时联系我们,我们将根据著作权人的要求立即更正或者删除有关内容。

GMT+8, 2024-4-27 16:10 , Processed in 0.137339 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表