licongjie的博客

专心、专注、专业
随笔 - 26, 文章 - 1, 评论 - 207, 引用 - 1
数据加载中……

实战小技巧系列(4):URL中包含中文参数造成乱码的解决之道

  中文乱码一直以来是WEB开发中比较常见的问题之一,对于初学者来说,各种各样的编码方式可能会有点不适应,本篇文章并不讲述这些编码,而是把自己遇到的一个小问题以及该问题的解决之法说明一下,希望对大家有用。

  问题:

  前段时间,在系统中做了一个类似于友情链接的功能块,一直运行良好,直到有一天加了类似于以下的链接地址:http://www.****.com/user.aspx?id=水天,就出现大问题了:

  1、从IE地址栏中直接输入这个地址,访问没错;

  2、做一个静态页,其中包括这个超链接,点击访问也没错;

  3、就是把这个链接添加到这个功能块中,点击访问那边接收到的是乱码。

  一开始,被这个问题也搞得头大,在google了一把后,总算是把问题给搞清楚了,其实只要这个链接地址不经过任何编码传递是不会有问题的。但就是加到了这个功能块后,再点击,虽然这个时候在IE地址栏里显示的还是"http://www.****.com/user.aspx?id=水天",但真正传递过去的参数"水天"其实已经经过类似于Server.UrlEncode的操作了,当然默认是utf-8编码,正是由于这个原因,如果对方系统不进行相应的解码,直接操作该参数,就产生了以上的错误。

  解决方法:

  网上有很多解决之道,最常见的莫过于以下几点:

  1、在web.config里配制<globalization requestEncoding="gb2312" responseEncoding="gb2312" />,这个方法确实可行,但我想很多人不想用这种方法来解决,把整个项目的请求和回应都定为gb2312,我觉得不是一个好办法,有点本末倒置了,毕竟这会导致很多其它问题的出现。

  2、把要包含该链接的aspx文档,修改其charset属性为gb2312。这个方法到也可以接受,不过对于该文中的问题还不是最好的方法,因为该功能块是可以动态添加到任何页面的,难道要去修改所有的页面?想想还是不太合适。

  3、直接用Server.UrlEncode和Server.Decode进行加码和解码操作,这种方法对于发送方和接收方都在一个项目中是可行的,现在的问题是,我们要随意去访问别人的系统,所以只能弃用此方法了。

  4、采用HttpUtility.UrlEncode(query, System.Text.Encoding.GetEncoding("GB2312"));对链接中的参数值进行gb2312的编码,这种方法,对方不用进行任何解码操作,直接接收参数则不会出现乱码。

  一般提到最多的也就上面4种方法,其它的也跟这些大同小异。仔细分析后,觉得还是第4种方法最适合解决当前问题,把中文参数进行如4中的操作。但又出现另外一个问题,由于这是一个用户可以自由输入链接地址的功能,所以首先要做的就是得先分析这些链接URL,解析出参数,再对这些参数进行4中操作,然后再合拼成原来的URL地址。

  幸亏,URL参数解析C#已经有类库的支持,不用再去写那些复杂的正则表达式来匹配了。这里我也不详细说了,直接贴出原码:

public static string InitChineseUrl(string chineseUrl)
{
Uri url = new Uri(chineseUrl);
System.Collections.Specialized.NameValueCollection nv = System.Web.HttpUtility.ParseQueryString(url.Query, System.Text.Encoding.GetEncoding("utf-8"));
string query = "";
for (int i = 0; i < nv.Count; i++)
{
if (query.Trim() == string.Empty)
{
query = "?" + nv.Keys[i] + "=" + HttpUtility.UrlEncode(nv[i], System.Text.Encoding.GetEncoding("GB2312"));
}
else
{
query += "&" + nv.Keys[i] + "=" + HttpUtility.UrlEncode(nv[i], System.Text.Encoding.GetEncoding("GB2312"));
}
}
string u = chineseUrl.Split('?')[0] + query;
return u;
}

  这里我是把所有的参数都进行gb2312编码操作了,反正参数如果是英文或者是数字,经过这些操作后还是不变的。

posted on 2008-05-05 10:07 李.net 阅读(2072) 评论(18)  编辑 收藏

评论

#1楼    回复  引用  查看    

请问如果URL是这样的如何解决
http://baidu.com?a=&&b=2
如何得到a的值
2008-05-05 10:54 | lcg22it      

#2楼    回复  引用  查看    

这个。。。。。

帅哥啊。。。。。整个字符串调用UrlEncode就可以了,没必要一个个参数拆分开来编码再串起来。。。
2008-05-05 11:06 | 没有昵称      

#3楼 [楼主]   回复  引用  查看    

@lcg22it
如果不是特殊的应用,我觉得用server.urlEncode先编码再接收的时候用server.decode解码就可以了
2008-05-05 11:08 | 李.net      

#4楼    回复  引用  查看    

@lcg22it
a的值为空啊。
2008-05-05 11:10 | 没有昵称      

#5楼    回复  引用  查看    

@lcg22it
如果你想让a等于字符串“&”,必须写a = UrlEncode("&")。
到时候url里面就不是?a=&&b=2这样子了。
自己试试
2008-05-05 11:11 | 没有昵称      

#6楼    回复  引用  查看    

我有个问题哦
就是我把动态生成静态的了,然后再这个静态页面中传递中文参数到动态页面,
好像怎么搞都不行,感觉是页面编码的问题,尝试了一下,没成功。
2008-05-05 11:47 | Longkin      

#7楼 [楼主]   回复  引用  查看    

@没有昵称
整个用是不行的,你可以试一下,它会把://这些都编码的,要不然,我干嘛费这么大劲把它分开来
2008-05-05 12:06 | 李.net      

#8楼 [楼主]   回复  引用  查看    

@Longkin
可以试一下escape把中文编码一下
2008-05-05 12:07 | 李.net      

#9楼    回复  引用  查看    

escape用了不行
不好意思,可能我刚才没有说清楚,我是在客户端通过Url传值,然后怎样在服务器端得到a的值(http://baidu.com?a=&&b=2
2008-05-05 12:42 | lcg22it      

#10楼    回复  引用  查看    

有空瞧瞧
2008-05-05 12:44 | 留恋星空      

#11楼    回复  引用  查看    

@lcg22it
这个url有问题,如果想在服务器端得到a的值为&,传递的url应该是:
http://baidu.com?a=%26&b=2

querystring中的键和值都是要经过urlencode后方能传递
2008-05-05 13:38 | Klesh Wong      

#12楼    回复  引用  查看    

楼主,统一编码很重要哦,要是一个项目中有多种编码,日后维护起来一定很头痛.如果说客户端传过来的值是utf8 encoding然后读的时候得到乱码则说明楼主的项目应该是gb2312编码的,既然如此,通过web.config指定客户端以gb2312编码来传值是比较妥当的做法.
或者把编码全部统一转换到utf8也是一劳永逸的做法.因为.net本身大量采用utf8编码,现在windows内部使用的也是unicode,理论上来讲,使用utf8反而会比较快,节省了许多内部编码转换的消耗.

不太明白为何楼主会最终选择增加一个函数来处理URL呢?这种处理方式似乎不透明吧?
2008-05-05 13:50 | Klesh Wong      

#13楼 [楼主]   回复  引用  查看    

@Klesh Wong
这个问题的环境不一样,不是同一个项目中的,如果是同一个项目中处理的话,有很多方法可以实现,用server.encode一下最简单不过了。现在现在的问题类似于一个友情链接的URL,这个时候,对方的系统有可能是ASP,也有可能是PHP、JSP都有可能,在这个时候,对方都是直接接收参数的,不会去做任何解析操作,所以我这边得做这样的处理
2008-05-05 13:57 | 李.net      

#14楼    回复  引用  查看    

@李.net
原来是这样子...
那楼主应该是用utf8的了,然后需要生成基于gb2312的url...
那这样的处理还是比较合理的.
2008-05-05 15:09 | Klesh Wong      

#15楼 [楼主]   回复  引用  查看    

@Klesh Wong
呵呵是的,我不想因为这样一个功能而把编码改成gb2312的,所以做这一特殊处理
2008-05-05 15:49 | 李.net      

#16楼    回复  引用  查看    

我覺得還是不行,因為這里是繁體服務器,Server.UrlEncode只對繁體的文字能正確解析,但是對簡體就亂碼了。
能否有更多的方法,因為還有越南文,韓文等
2008-05-05 16:39 | Nina      

#17楼 [楼主]   回复  引用  查看    

@Nina
如果是其它体的话,就不应该是gb2312了,HttpUtility.UrlEncode(nv[i], System.Text.Encoding.GetEncoding("GB2312"));
这里应该是相应的编码代号
2008-05-05 17:03 | 李.net      

#18楼    回复  引用  查看    

和JS处理乱码问题思路基本相同!
2008-05-06 01:40 | 镜涛      

标题  
姓名  
主页
Email (只有博主才能看到) 
验证码 *  看不清,换一张
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
 
向地震灾区捐赠爱心