开发者社区> 长征6号> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

encodeURI之URL中文参数问题

简介:
+关注继续查看

********************************************************************
*                                                 版权声明
*
* 本文以Creative Commons的知识共享署名-非商业性使用-相同方式共享发布,请严格遵循该授权协议。
* 本文首发于博客园, 此声明为本文章中不可或缺的一部分。
* 作者网名:    浪子
* 作者EMAILdayichen (at)163.com
* 作者BLOG:  Http://Www.Cnblogs.Com/Walkingboy
*
********************************************************************

encodeURI之URL中文参数问题

-Written by 浪子@cnblogs.com  (07-01-26)

摘要:

我们在页面和页面间传递参数,最常用的一种方式就是通过url传递,如果涉及到中文或者其他特殊字符的时候,一般会使用encodeURI在Client端进行编码,Server端直接使用QueryString[]获取值(asp.net会自动帮我们进行解码),却无法料到,这样子也会出现错误,发现form的action地址竟然和url地址不符?asp.net在为form设置action的时候似乎进行了一定的编码(我还未知)......

 

一、Client端的QueryString:

自从使用了CallbackPlus之后,我们的编程模式越来越多的转向了Client端编码,而参数又经常通过url的形势传递,所以就写了个客户端的QueryString集中分析参数值

 


function QueryString(paraName){
    var url = window.location.search;
    var para = url.substr(url.indexOf(paraName));
    var andIndex = para.indexOf("&");
    var paras;
    if(andIndex>-1){
        paras = para.substr(0,para.indexOf("&"));
    }else{
        paras = para;
    }
    var paraValue = paras.split("=")[1];
    if(paraValue){
        return decodeURI(paraValue);
    }else{return "";};
}

 

原来一直都使用的好好,今天一个同事突然跟我说,QueryString的时候,出现“被解码的URI不是合法的编码”。问题很奇怪,因为第一遍进入的时候,已经在Client端正确识别到了该参数,但是触发某按钮执行PostBack之后,就会出现该问题。经过检查,发现第一次进入页面的时候,IE URL和form的action地址不一样,PostBack之后IE URL被修改为跟from的action一样(参考demo代码的encodeURI.aspx)。经过测试之后,发现这个问题只存在于中文或者特殊字符编码的URL上。在网上查找了很多资料都没有得到正确答案(比如设置web.config 的requestEncoding,responseEncodeing.),与阿不沟通后也没能得到有效的解决方法。后来想,既然正常的URL不会出问题,那就把中文编码为非特殊的字串就好了......

二、自定义的编码和解码方法: 

查找了很多编码和解码方法,一直都没有合适的,所以只能自己写一个这样的函数。因为这个编码和解码Client和Server都需要调用,所以也没有打算写得很复杂。

在查找资料的时候,从birdshome解决WebControl的doPostBack参数传递问题 那里得到了一个按长度分割编码后字串的思路,觉得相对比较简单和好写,所以就决定暂时采用这种思路进行设计。

修改函数如下:

Client :


function QueryString(paraName,isCusEncode){
    var url = window.location.search;
    
    var para = url.substr(url.indexOf(paraName));
    var andIndex = para.indexOf("&");
    var paras;
    if(andIndex>-1){
        paras = para.substr(0,para.indexOf("&"));
    }else{
        paras = para;
    }
    var paraValue = paras.split("=")[1];
    if(paraValue){
        return kdecode(paraValue,isCusEncode);
    }else{return "";};
}
function kencode(unzipStr,isCusEncode){
    if(isCusEncode){
        var zipArray = new Array();
        var zipstr = "";
        var lens = new Array();
        for(var i=0;i<unzipStr.length;i++){
         var ac = unzipStr.charCodeAt(i);
         zipstr += ac;
         lens = lens.concat(ac.toString().length);
        }
        zipArray = zipArray.concat(zipstr);
        zipArray = zipArray.concat(lens.join("O"));
        return zipArray.join("N");
    }else{
        return encodeURI(unzipStr);
    }
}
function kdecode(zipStr,isCusEncode){
        if(isCusEncode){
        var zipArray = zipStr.split("N");
        var zipSrcStr = zipArray[0];
        var zipLens = zipArray[1].split("O");
        var uzipStr = "";
        
        for(var j=0;j<zipLens.length;j++){
            var charLen = parseInt(zipLens[j]);
            uzipStr+= String.fromCharCode(zipSrcStr.substr(0,charLen));
            zipSrcStr = zipSrcStr.slice(charLen,zipSrcStr.length);
        }        
        return uzipStr;
    }else{
        return decodeURI(zipStr);
    }
}

        当然Server端也是需要对应的函数的:

 


public static string KEncode(string unzipStr)
        {
            return KEncode(unzipStr, false);
        }
        public static string KEncode(string unzipStr,bool isCusEncode)
        {
            if (isCusEncode)
            {
                string zipstr = string.Empty;
                StringCollection lens = new StringCollection();
                char[] chars = unzipStr.ToCharArray();
                for (int i = 0; i < chars.Length; i++)
                {
                    int ac = (int)chars[i];
                    zipstr += ac.ToString();
                    lens.Add(ac.ToString().Length.ToString());
                }
                string len = string.Empty;
                for (int i = 0; i < lens.Count; i++)
                {
                    if (i+1 == lens.Count)
                    {
                        len += lens[i];
                    }
                    else
                    {
                        len += lens[i]+"O";
                    }
                }
                return zipstr + "N" + len;
            }
            else
            {
                return HttpUtility.UrlEncode(unzipStr);
            }
            
        }
        public static string KDecode(string zipStr)
        {
            return KDecode(zipStr, false);
        }
        public static string KDecode(string zipStr, bool isCusEncode)
        {
            if (isCusEncode)
            {
                string[] zipArray = zipStr.Split(new string[1] { "N" }, StringSplitOptions.RemoveEmptyEntries);
                string zipSourceStr = zipArray[0];
                string[] zipLens = zipArray[1].Split(new string[1] { "O" }, StringSplitOptions.RemoveEmptyEntries);//no Zero,is "O"
                string uzipStr = "";
                for (int j = 0; j < zipLens.Length; j++)
                {
                    int charLen = int.Parse(zipLens[j]);
                    uzipStr += (char)(int.Parse((zipSourceStr.Substring(0, charLen))));
                    zipSourceStr = zipSourceStr.Remove(0, charLen);
                }
                return uzipStr;
            }
            else
            {
                return HttpUtility.UrlDecode(zipStr);
            }
        }

三、后话:

可能这是最差的解决方案,不知道园子里是否有其他人发现这个问题,并且有更好的解决方案?

问题描述和解决方法demo代码示例:Download
  
Updated :本来还担心QueryString的长度限制问题,后来阿不提供的相关的资料:IE地址栏的最大长度(-Maximum URL length is 2,083 characters in Internet Explorer.),也就放心了,应该不会超过这个限制的。



本文转自浪子博客园博客,原文链接:http://www.cnblogs.com/walkingboy/archive/2007/01/26/encodeURIAndFormAction_Chinese.html,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
全方位解读服务网格(Service Mesh)的背景和概念
为了解决微服务框架的侵入性问题,我们引入服务网格。
1213 0
PolarDB 并行查询的前世今生
本文会深入介绍PolarDB MySQL在并行查询这一企业级查询加速特性上做的技术探索、形态演进和相关组件的实现原理,所涉及功能随PolarDB MySQL 8.0.2版本上线。
478 0
企业内部应用接入钉钉获取部门及人员信息
企业内部应用接入钉钉,同时通过API获取当前企业下部门及人员信息
1161 0
MySQL模糊查询再也用不着 like+% 了!
我们都知道 InnoDB 在模糊查询数据时使用 "%xx" 会导致索引失效,但有时需求就是如此,类似这样的需求还有很多,例如,搜索引擎需要根基用户数据的关键字进行全文查找,电子商务网站需要根据用户的查询条件,在可能需要在商品的详细介绍中进行查找,这些都不是B+树索引能很好完成的工作。 通过数值比较,范围过滤等就可以完成绝大多数我们需要的查询了。但是,如果希望通过关键字的匹配来进行查询过滤,那么就需要基于相似度的查询,而不是原来的精确数值比较,全文索引就是为这种场景设计的。
25665 0
阿里云云原生一体化数仓正式发布  助力企业数据驱动业务创新
云原生一体化数仓是集阿里云大数据产品MaxCompute、DataWorks、Hologres三种产品能力于一体的一站式大数据处理平台。核心是3个一体化和全链路数据治理能力,包括离线实时一体、湖仓一体、分析服务一体、全链路数据治理。
1589 0
全面公测|Grafana服务:一张图表胜过千行指标&日志
Grafana 帮助运维人员轻松处理各类运维过程中遇到的各类数据可视化与分析难题。目前阿里云 Grafana 服务全面免费公测,帮助企业轻松构建运维数据可视化平台,轻松实现数据驱动运维!
1135 0
一起学Golang系列(五)初次接触Go语言可能遇到的各种坑!
前面介绍了Go语言的基础语法,所谓磨刀不误砍柴工,希望大家还是能熟悉掌握这些基础知识,这样后面真正学起Go来才会得心应手。 作为初学者。Go语言的语法有些和java类似,但也有很多不一样的地方。刚开始都会遇到各种各样的坑。下面就来总结下学习go语言的过程中,遇到的各种坑。
997 0
设备接入--海康摄像头SDK
springboot-对接海康摄像头,兼容window和Linux环境
1318 0
Flink SQL 在快手的扩展和实践
快手实时计算团队技术专家张静、张芒在 FFA 2021 的分享
1128 0
无影云桌面,企业与个人的应用神器
阿里云无影云桌面( Elastic Desktop Service)的原产品名为弹性云桌面,融合了无影产品技术后更名升级。它可以为您提供易用、安全、高效的云上桌面服务,帮助您快速构建、高效管理桌面办公环境,提供安全、灵活的办公体系。
276274 0
+关注
1222
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载