php url编码码 为什么 中文 加% 原因

4257人阅读
&先来看看三个url:
url1. /爱宝的妍url2. /%E7%88%B1%E5%AE%9D%E7%9A%84%E5%A6%8D (UTF-8 编码)url3. /%B0%AE%B1%A6%B5%C4%E5%FB (GBK 编码)
这三个url指向同一个网页,而且都能够访问。其实,如果你的浏览器是中文环境下的,IE设置“以UTF8发送URL”,那么在IE里输入url1,服务器端得到的是url2;在firefox里输入url1,服务器端得到的是url3。这是为什么呢?听下文分解(分析部分内容转自http://blog.csdn.net/yzhz/archive//1676796.aspx)。
一、问题:
编码问题是JAVA初学者在web开发过程中经常会遇到问题,网上也有大量相关的文章介绍,但其中很多文章并没有对URL中使用了中文等非ASCII的字符造成服务器后台程序解析出现乱码的问题作出准确的解释和说明。本文将详细介绍由于在URL中使用了中文等非ASCII的字符造成乱码的问题。
1、在URL中中文字符通常出现在以下两个地方:
(1)、Query String中的参数值,比如http://search./search/offer_search.htm?keywords=中国
(2)、servlet path,比如:http://search./selloffer/中国.html
2、出现乱码问题的原因主要是以下几方面:
(1)、浏览器:我们的客户端(浏览器)本身并没有遵循URI编码的规范(http://www.w3.org/International/O-URL-code.html)。
(2)、Servlet服务器:Servlet服务器的没有正确配置。
(3)、开发人员并不了解Servlet的规范和API的含义。
二、基础知识:
1、一个http请求经过的几个环节:
浏览器(ie firefox)【get/post】------------&Servlet服务器-------------------------------&浏览器显示
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 编码&&&&&&&&&&&&&&&&&& 解码成unicode,然后将显示的内容编码&&&&&&&&& 解码
(1) 浏览器把URL(以及post提交的内容)经过编码后发送给服务器。
(2) 这里的Servlet服务器实际上指的是由Servlet服务器提供的servlet实现ServletRequestWrapper,不同应用服务器的servlet实现不同,这些servlet的实现把这些内容解码转换为unicode,处理完毕后,然后再把结果(即网页)编码返回给浏览器。
(3) 浏览器按照指定的编码显示该网页。当对字符串进行编码和解码的时候都涉及到字符集,通常使用的字符集为ISO8859-1、GBK、UTF-8、UNICODE。
2、URL的组成:
域名:端口/contextPath/servletPath/pathInfo?queryString
1、ContextPath是在Servlet服务器的配置文件中指定的。
对于weblogic:
contextPath是在应用的weblogic.xml中配置。
&context-root&/&/context-root&
对于tomcat:
contextPath是在server.xml中配置。
&Context path=&/& docBase=&D:/server/blog.war& debug=&5& reloadable=&true& crossContext=&true&/&
对于jboos:
contextPath是在应用的jboss-web.xml中配置。
&jboss-web&
&context-root&/&/context-root&
&/jboss-web&
2、ServletPath是在应用的web.xml中配置。
&servlet-mapping&
&servlet-name&Example&/servlet-name&
&url-pattern&/example/*&/url-pattern&
&/servlet-mapping&
2、Servlet API
我们使用以下servlet API获得URL的值及参数。
request.getParameter(&name&);
// 获得queryString的参数值(来自于get和post),其值经过Servlet服务器URL Decode过的
request.getPathInfo();
// 注意:pathinfo返回的字符串是经过Servlet服务器URL Decode过的。
requestURI = request.getRequestURI(); // 内容为:contextPath/servletPath/pathinfo 浏览器提交过来的原始数据,未被Servlet服务器URL Decode过。
3、开发人员必须清楚的servlet规范:
(1) HttpServletRequest.setCharacterEncoding()方法 仅仅只适用于设置post提交的request body的编码而不是设置get方法提交的queryString的编码。该方法告诉应用服务器应该采用什么编码解析post传过来的内容。很多文章并没有说明这一点。
(2) HttpServletRequest.getPathInfo()返回的结果是由Servlet服务器解码(decode)过的。
(3) HttpServletRequest.getRequestURI()返回的字符串没有被Servlet服务器decoded过。
(4) POST提交的数据是作为request body的一部分。
(5) 网页的Http头中ContentType(&text/ charset=GBK&)的作用:
(a) 告诉浏览器网页中数据是什么编码;
(b) 表单提交时,通常浏览器会根据ContentType指定的charset对表单中的数据编码,然后发送给服务器的。
这里需要注意的是:这里所说的ContentType是指http头的ContentType,而不是在网页中meta中的ContentType。
三、下面我们分别从浏览器和应用服务器来举例说明:
URL:http://localhost:8080/example/中国?name=中国
汉字&&&& 编码&&&&&&& 二进制表示
中国&&&& UTF-8&&&&&& 0xe4 0xb8 0xad 0xe5 0x9b 0xbd[-28, -72, -83, -27, -101, -67]
中国&&&& GBK&&&&&&&& 0xd6 0xd0 0xb9 0xfa[-42, -48, -71, -6]
中国&&&& ISOx3f,0x3f[63, 63]信息失去
(一)、浏览器
1、GET方式提交,浏览器会对URL进行URL encode,然后发送给服务器。
(1) 对于中文IE,如果在高级选项中选中总以UTF-8发送(默认方式),则PathInfo是URL Encode是按照UTF-8编码,QueryString是按照GBK编码。
http://localhost:8080/example/中国?name=中国
实际上提交是:
GET /example/%E4%B8%AD%E5%9B%BD?name=%D6%D0%B9%FA
(2) 对于中文IE,如果在高级选项中取消总以UTF-8发送,则PathInfo和QueryString是URL encode按照GBK编码。
实际上提交是:
GET /example/%D6%D0%B9%FA?name=%D6%D0%B9%FA
(3) 对于中文firefox,则pathInfo和queryString都是URL encode按照GBK编码。实际上提交是:
GET /example/%D6%D0%B9%FA?name=%D6%D0%B9%FA
很显然,不同的浏览器以及同一浏览器的不同设置,会影响最终URL中PathInfo的编码。对于中文的IE和FIREFOX都是采用GBK编码QueryString。
小结:解决方案:
1、URL中如果含有中文等非ASCII字符,则浏览器会对它们进行URLEncode。为了避免浏览器采用了我们不希望的编码,所以最好不要在URL中直接使用非ASCII字符,而采用URL Encode编码过的字符串%.
比如:URL:http://localhost:8080/example/中国?name=中国
建议:URL:http://localhost:8080/example/%D6%D0%B9%FA?name=%D6%D0%B9%FA
我们建议URL中PathInfo和QueryString采用相同的编码,这样对服务器端处理的时候会更加简单。
2、还有一个问题,我发现很多程序员并不明白URL Encode是需要指定字符集的。不明白的人可以看看这篇文档:.cn/Java_Docs/html/zh_CN/api/java/net/URLEncoder.html
3、 POST提交
对于POST方式,表单中的参数值对是通过request body发送给服务器,此时浏览器会根据网页的ContentType(&text/ charset=GBK&)中指定的编码进行对表单中的数据进行编码,然后发给服务器。在服务器端的程序中我们可以通过Request.setCharacterEncoding() 设置编码,然后通过request.getParameter获得正确的数据。
解决方案:
1、从最简单,所需代价最小来看,我们对URL以及网页中的编码使用统一的编码对我们来说是比较合适的。
如果不使用统一编码的话,我们就需要在程序中做一些编码转换的事情。这也是我们为什么看到有网络上大量的资料介绍如何对乱码进行处理,其中很多解决方案都只是一时的权宜之计,没有从根本上解决问题。
(二)、Servlet服务器
&&&&&&&&& Servlet服务器实现的Servlet遇到URL和POST提交的数据中含有%的字符串,它会按照指定的字符集解码。下面两个Servlet方法返回的结果都是经过解码的:
request.getParameter(&name&);&
request.getPathInfo();
这里所说的&指定的字符集&是在应用服务器的配置文件中配置。
(1) tomcat服务器
对于tomcat服务器,该文件是server.xml
&Connector port=&8080& protocol=&HTTP/1.1&
maxThreads=&150& connectionTimeout=&20000&
redirectPort=&8443& URIEncoding=&GBK&/&URIEncoding告诉服务器servlet解码URL时采用的编码。
&Connector port=&8080& ... useBodyEncodingForURI=&true& /&
useBodyEncodingForURI告诉服务器解码URL时候需要采用request body指定的编码。
(2) weblogic服务器
对于weblogic服务器,该文件是weblogic.xml&
&input-charset&
&java-charset-name&GBK&/java-charset-name&
&/input-charset&
(三)浏览器显示
浏览器根据http头中的ContentType(&text/ charset=GBK&),指定的字符集来解码服务器发送过来的字节流。我们可以调用HttpServletResponse.setContentType()设置http头的ContentType。
1、URL中的PathInfo和QueryString字符串的编码和解码是由浏览器和应用服务器的配置决定的,我们的程序不能设置,不要期望用request.setCharacterEncoding()方法能设置URL中参数值解码时的字符集。所以我们建议URL中不要使用中文等非ASCII字符,如果含有非ASCII字符的话要使用URLEncode编码一下,比如:
http://localhost:8080/example1/example/中国
正确的写法:
http://localhost:8080/example1/example/%E4%B8%AD%E5%9B%BD
并且我们建议URL中不要在PathInfo和QueryString同时使用非ASCII字符,比如:http://localhost:8080/example1/example/中国?name=中国
原因很简单:不同浏览器对URL中PathInfo和QueryString编码时采用的字符集不同,但应用服务器对URL通常会采用相同的字符集来解码。
2、我们建议URL中的URL Encode编码的字符集和网页的contentType的字符集采用相同的字符集,这样程序的实现就很简单,不用做复杂的编码转换。
到这里大家该明白url编码的原理了吧。再回过头来看看本文一开始给出的三个url。/爱宝的妍 属于PathInfo,所以根据IE以及Firefox默认设置,ie用utf8 encode了该url,而firefox用gbk encode的,随之服务器端得到了url2和url3不同的url。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:332948次
积分:4683
积分:4683
排名:第2198名
原创:119篇
转载:74篇
评论:133条
(2)(3)(2)(4)(1)(2)(2)(1)(2)(1)(1)(1)(1)(6)(2)(7)(3)(3)(3)(1)(7)(6)(5)(4)(3)(1)(1)(2)(1)(2)(1)(2)(2)(3)(2)(6)(3)(7)(6)(5)(2)(5)(10)(6)(3)(2)(5)(5)(8)(6)(2)(5)(4)(4)(12)loadrunner的url编码和中文参数化总结_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
文档贡献者贡献于
评价文档:
9页免费6页免费9页免费6页¥2.004页免费4页免费6页1下载券4页免费3页免费2页免费
loadrunner的url编码和中文参数化总结|l​o​a​d​r​u​n​n​e​r​的​u​r​l​编​码​和​中​文​参​数​化​总​结
把文档贴到Blog、BBS或个人站等:
普通尺寸(450*500pix)
较大尺寸(630*500pix)
大小:6.70KB
登录百度文库,专享文档复制特权,财富值每天免费拿!
你可能喜欢页面导航:
→ 正文内容
在JavaScript中通过URL传递汉字的方法
利用JavaScript通过URL方式向后台代码传值是一种经常用到的手段,但在传递汉字时经常会出现字符不全或变成乱码的问题,其原因是由于客户端IE浏览器的编码方式为GB2312(简体中文版WINDOWS的默认设置),而后台的C#代码使用utf8编码(创建WEB工程的默认配置)。 网上有很多方案解决该问题,如将web.config的编码方式改为GB2312、在客户端通过escape先编码再传,个心体会都不是很理想或有些特殊字符不支持。经过比较我决定使用encodeURIComponent在客户端进行编码,再传值,除了“/”不支持(但实际开发中很少需要传递该值,如果真有此请况,再加一层判断即可。 encodeURIComponent的帮助文档如下: encodeURIComponent&方法 将文本字符串编码为一个统一资源标识符&(URI)&的一个有效组件。 encodeURIComponent(&encodedURIString&)& 必选的&encodedURIString&参数代表一个已编码的&URI&组件。 说明 encodeURIComponent&方法返回一个已编码的&URI。如果您将编码结果传递给&decodeURIComponent&,那么将返回初始的字符串。因为encodeURIComponent&方法对所有的字符编码,请注意,如果该字符串代表一个路径,例如&/folder1/folder2/default.html&,其中的斜杠也将被编码。这样一来,当该编码结果被作为请求发送到&web&服务器时将是无效的。如果字符串中包含不止一个&URI&组件,请使用&encodeURI&方法进行编码。 要求 版本&5.5 请参阅 decodeURI&方法&|&decodeURIComponent&方法 应用于:&Global&对象 我做了一个小例子来展现该效果&& Default.aspx代码:
代码如下:&%@&Page&Language="C#"&AutoEventWireup="true"&&CodeFile="Default.aspx.cs"&Inherits="_Default"&%&& &!DOCTYPE&html&PUBLIC&"-//W3C//DTD&XHTML&1.0&Transitional//EN"&"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&& &html&xmlns="http://www.w3.org/1999/xhtml"&&& &head&runat="server"&& &&&&&title&无标题页&/title&& &/head&& &script&type="text/javascript"&language="javascript"&& &&&&function&callURL(Value1,&Value2)& &&&&{& &&&&&&&&document.URL&=&"Default.aspx?Value1="&+&encodeURIComponent(Value1)&+&"&Value2="&+&encodeURIComponent(Value2);& &&&&}& &/script&& &body&& &&&&&form&id="form1"&runat="server"&& &&&&&div&& &&&&&&&&Value1=&input&id="Text1"&type="text"&value=""/&&br&/&& &&&&&&&&Value2=&input&id="Text2"&type="text"&value="中华人民共和国"/&& &&&&&&&&&br&/&& &&&&&&&&&input&id="Button1"&type="button"&value="提交"&onclick="callURL(Text1.value,&Text2.value)"/&&/div&& &&&&&/form&& &/body&& &/html&& Default.aspx.cs代码:
代码如下:using&S& using&System.D& using&System.C& using&System.W& using&System.Web.S& using&System.Web.UI;& using&System.Web.UI.WebC& using&System.Web.UI.WebControls.WebP& using&System.Web.UI.HtmlC& public&partial&class&_Default&:&System.Web.UI.Page&& {& &&&&protected&void&Page_Load(object&sender,&EventArgs&e)& &&&&{& &&&&&&&&string&tmpValue1&=&"";& &&&&&&&&string&tmpValue2&=&"";& &&&&&&&&if&(Request.QueryString["Value1"]&!=&null)& &&&&&&&&{& &&&&&&&&&&&&tmpValue1&=&Request.QueryString["Value1"].ToString();& &&&&&&&&}& &&&&&&&&if&(Request.QueryString["Value2"]&!=&null)& &&&&&&&&{& &&&&&&&&&&&&tmpValue2&=&Request.QueryString["Value2"].ToString();& &&&&&&&&}& &&&&&&&&Response.Write("Value1="&+&tmpValue1&+&"&br&/&"&+&"Value2="&&+&tmpValue2);& &&&&}& }
您可能感兴趣的文章:
上一篇:下一篇:
最 近 更 新
热 点 排 行
12345678910Asp解决URL中文编解码问题_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
文档贡献者贡献于
评价文档:
3页免费13页免费5页免费5页免费3页免费7页免费1页免费2页免费2页免费1页免费
喜欢此文档的还喜欢77页7下载券3页免费97页7下载券12页免费2页免费
Asp解决URL中文编解码问题|
把文档贴到Blog、BBS或个人站等:
普通尺寸(450*500pix)
较大尺寸(630*500pix)
大小:1.96KB
登录百度文库,专享文档复制特权,财富值每天免费拿!
你可能喜欢关于URL编码 - 看引擎 KENGINE | 看看新闻网 IT资讯
关于URL编码
URL就是网址,只要上网,就一定会用到。
一般来说,URL只能使用英文字母、阿拉伯数字和某些标点符号,不能使用其他文字和符号。比如,世界上有英文字母的网址””,但是没有希腊字母的网址”http://www.aβγ.com”(读作阿尔法-贝塔-伽玛.com)。这是因为网络标准RFC 1738做了硬性规定:
"...Only alphanumerics [0-9a-zA-Z], the special characters "$-_.+!*'()," [not including the quotes - ed], and reserved characters used for their reserved purposes may be used unencoded within a URL."
"只有字母和数字[0-9a-zA-Z]、一些特殊符号"$-_.+!*'(),"[不包括双引号]、以及某些保留字,才可以不经过编码直接用于URL。"
这意味着,如果URL中有汉字,就必须编码后使用。但是麻烦的是,RFC 1738没有规定具体的编码方法,而是交给应用程序(浏览器)自己决定。这导致”URL编码”成为了一个混乱的领域。
下面就让我们看看,”URL编码”到底有多混乱。我会依次分析四种不同的情况,在每一种情况中,浏览器的URL编码方法都不一样。把它们的差异解释清楚之后,我再说如何用Javascript找到一个统一的编码方法。
2.1 网址路径中包含汉字
打开IE(我用的是8.0版),输入网址”
注意,”春节”这两个字此时是网址路径的一部分。
查看HTTP请求的头信息,会发现IE实际查询的网址是”http://zh.wikipedia.org/wiki/%E6%98%A5%E8%8A%82″。也就是说,IE自动将”春节”编码成了”%E6%98%A5%E8%8A%82″。
我们知道,”春”和”节”的utf-8编码分别是&# A5″和&#A 82″,因此,”%E6%98%A5%E8%8A%82″就是按照顺序,在每个字节前加上%而得到的。(具体的转码方法,请参考我写的《字符编码笔记》。)
在Firefox中测试,也得到了同样的结果。所以,结论1就是,网址路径的编码,用的是utf-8编码。
2.2 查询字符串包含汉字
在IE中输入网址”/s?wd=春节”。注意,”春节”这两个字此时属于查询字符串,不属于网址路径,不要与情况1混淆。
查看HTTP请求的头信息,会发现IE将”春节”转化成了一个乱码。
切换到十六进制方式,才能清楚地看到,”春节”被转成了”B4 BA BD DA”。
我们知道,”春”和”节”的GB2312编码(我的操作系统”Windows XP”中文版的默认编码)分别是”B4 BA”和”BD DA”。因此,IE实际上就是将查询字符串,以GB2312编码的格式发送出去。Firefox的处理方法,略有不同。它发送的HTTP Head是”wd=%B4%BA%BD%DA”。也就是说,同样采用GB2312编码,但是在每个字节前加上了%。
所以,结论2就是,查询字符串的编码,用的是操作系统的默认编码。
2.3 Get方法生成的URL包含汉字
前面说的是直接输入网址的情况,但是更常见的情况是,在已打开的网页上,直接用Get或Post方法发出HTTP请求。
根据台湾中兴大学吕瑞麟老师的试验,这时的编码方法由网页的编码决定,也就是由HTML源码中字符集的设定决定。
 &meta http-equiv="Content-Type" content="text/charset=xxxx"&
如果上面这一行最后的charset是UTF-8,则URL就以UTF-8编码;如果是GB2312,URL就以GB2312编码。举例来说,百度是GB2312编码,Google是UTF-8编码。因此,从它们的搜索框中搜索同一个词”春节”,生成的查询字符串是不一样的。
百度生成的是%B4%BA%BD%DA,这是GB2312编码。
Google生成的是%E6%98%A5%E8%8A%82,这是UTF-8编码。
所以,结论3就是,GET和POST方法的编码,用的是网页的编码。
2.4 Ajax调用的URL包含汉字
前面三种情况都是由浏览器发出HTTP请求,最后一种情况则是由Javascript生成HTTP请求,也就是Ajax调用。还是根据吕瑞麟老师的文章,在这种情况下,IE和Firefox的处理方式完全不一样。
举例来说,有这样两行代码:
  url = url + "?q=" +document.myform.elements[0]. // 假定用户在表单中提交的值是"春节"这两个字
  http_request.open('GET', url, true);
那么,无论网页使用什么字符集,IE传送给服务器的总是”q=%B4%BA%BD%DA”,而Firefox传送给服务器的总是”q=%E6%98%A5%E8%8A%82″。也就是说,在Ajax调用中,IE总是采用GB2312编码(操作系统的默认编码),而Firefox总是采用utf-8编码。这就是我们的结论4。
好了,到此为止,四种情况都说完了。假定前面你都看懂了,那么此时你应该会感到很头痛。因为,实在太混乱了。不同的操作系统、不同的浏览器、不同的网页字符集,将导致完全不同的编码结果。如果程序员要把每一种结果都考虑进去,是不是太恐怖了?有没有办法,能够保证客户端只用一种编码方法向服务器发出请求?回答是有的,就是使用Javascript先对URL编码,然后再向服务器提交,不要给浏览器插手的机会。因为Javascript的输出总是一致的,所以就保证了服务器得到的数据是格式统一的。Javascript语言用于编码的函数,一共有三个,最古老的一个就是escape()。虽然这个函数现在已经不提倡使用了,但是由于历史原因,很多地方还在使用它,所以有必要先从它讲起。
4.1 escape()
实际上,escape()不能直接用于URL编码,它的真正作用是返回一个字符的Unicode编码值。比如”春节”的返回结果是%u,也就是说在Unicode字符集中,”春”是第6625个(十六进制)字符,”节”是第8282个(十六进制)字符。
它的具体规则是,除了ASCII字母、数字、标点符号”@ * _ + – . /”以外,对其他所有字符进行编码。在\u0000到\u00ff之间的符号被转成%xx的形式,其余符号被转成%uxxxx的形式。对应的解码函数是unescape()。
所以,”Hello World”的escape()编码就是”Hello%20World”。因为空格的Unicode值是20(十六进制)。
还有两个地方需要注意。
首先,无论网页的原始编码是什么,一旦被Javascript编码,就都变为unicode字符。也就是说,Javascipt函数的输入和输出,默认都是Unicode字符。这一点对下面两个函数也适用。
4.2 encodeURI()
encodeURI()是Javascript中真正用来对URL编码的函数。它着眼于对整个URL进行编码,因此除了常见的符号以外,对其他一些在网址中有特殊含义的符号”; / ? : @ & = + $ , #”,也不进行编码。编码后,它输出符号的utf-8形式,并且在每个字节前加上%。
它对应的解码函数是decodeURI()。
需要注意的是,它不对单引号’编码。
4.3 encodeURIComponent()
最后一个Javascript编码函数是encodeURIComponent()。与encodeURI()的区别是,它用于对URL的组成部分进行个别编码,而不用于对整个URL进行编码。因此,”; / ? : @ & = + $ , #”,这些在encodeURI()中不被编码的符号,在encodeURIComponent()中统统会被编码。至于具体的编码方法,两者是一样。
它对应的解码函数是decodeURIComponent()。
No tags for this post.
除非注明,本站文章均为原创或编译,转载请注明: 文章来自
分享给朋友:
查看全部:

我要回帖

更多关于 php url编码 的文章

 

随机推荐