`

HTML中的GET和POST编码

阅读更多
一、问题:
        编码问题是JAVA初学者在web开发过程中经常会遇到问题,网上也有大量相关的文章介绍,但其中很多文章并没有对URL中使用了中文等非ASCII的字 符造成服务器后台程序解析出现乱码的问题作出准确的解释和说明。本文将详细介绍由于在URL中使用了中文等非ASCII的字符造成乱码的问题。
1、在URL中中文字符通常出现在以下两个地方:
(1)、Query String中的参数值,比如http://search.china.alibaba.com/search/offer_search.htm?keywords=中国
(2)、servlet path,比如:http://search.china.alibaba.com/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/html; 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]
中国   ISO8859-1 0x3f,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
(1) 对于中文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
2、我们建议URL中PathInfo和QueryString采用相同的编码,这样对服务器端处理的时候会更加简单。
2、还有一个问题,我发现很多程序员并不明白URL Encode是需要指定字符集的。不明白的人可以看看这篇文档:http://gceclub.sun.com.cn/Java_Docs/html/zh_CN/api/java/net/URLEncoder.html
2、 POST提交
        对于POST方式,表单中的参数值对是通过request body发送给服务器,此时浏览器会根据网页的ContentType("text/html; 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/html; 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的字符集采用相同的字符集,这样程序的实现就很简单,不用做复杂的编码转换。
分享到:
评论

相关推荐

    c# http post get

    * *描 述:实现HTTP协议中的GET、POST请求 * *使 用:HttpProc.WebClient client = new HttpProc.WebClient(); client.Encoding = System.Text.Encoding.Default;//默认编码方式,根据需要设置其他类型 client....

    response响应数据变成???&使用jquery发送带中文参数数据的get请求得到响应数据乱码解决过程

    一. response响应数据变成???的说明 request请求数据设置编码使用:request.setCharacterEncoding(“UTF-8”); response响应数据设置编码使用:...使用jquery发送post和get请求时,请求端和响应端均设置了编码,为

    js调用AJAX时Get和post的乱码解决方法

    在使用”get”时,抓取的页面最后加上编码类型 代码如下: &lt;&#37; 服务器端:servletactioncontext.getresponse().setcharacterencoding(“utf-8”); 客户端 网页特效p/jsp.html target=_blank &gt;jsp教程: &lt;&#...

    HttpRequest Get和Post调用其他页面的方法

    代码如下: //Get请求方式 private string RequestGet(string Url) { string PageStr = string.Empty;//用于存放还回的html Uri url = new Uri(Url);//Uri类 提供统一资源标识符 (URI) 的对象表示形式和对 URI ...

    HttpHelper万能框架 V2.2

    HttpHelper万能框架 轻松GET、玩转POST、HTML分析、无视编码、验证码提取、Cookie分析互转、Url格式化、加密、代理IP、证书、Json数据分析、执行JavaScript 【HttpHelper万能框架】是什么? 大家好我是苏飞 , 我的...

    ajax中文乱码如何解决

    但这个方法在POST方式中却不起作用。大家都知道GET方式提交数据有长度限制,有时我们必须使用POST方式来提交数据。 但对于POST方式,使用上述的几种方法经过多次测试,问题依旧。我郁闷了好几天。 今天把问题解决...

    Html-JavaScriptHelper帮助类.zip

    以GET方式抓取远程页面内容 以POST方式抓取远程页面内容 压缩HTML输出 过滤指定HTML标签 加载文件块 加载CSS样式文件 加载javascript脚本文件 弹出警告信息并跳转到指定页面地址 弹出信息 无跳转动作 执行js命令 ...

    最新HttpHelps类

    HttpHelps类,用来实现Http访问,Post或者Get方式的,直接访问,带Cookie的,带证书的等方式,可以设置代理,无视编码问题。 只需要传参数就行了, 都是现成的方法,类是源代码大家也可以自行修改,比拼Sqlhelper类,...

    Ajax 对象 包含post和get两种异步传输方式

    代码如下: /** * @author Supersha * @QQ:770104121 */ &lt;!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01//EN” “http://www.w3.org/TR/html4/strict.dtd”&gt; &lt;... [removed] //注意,编码要同意为utf-8才能

    AircallUserFeed:Web应用程序,使用GET和POST方法从RESTful API中获取调用对象。 用户可以在提要中存档和取消存档这些调用,从而直接影响API上的数据状态

    概括 该测试的目的是使您编写一个小型ReactJS应用程序。 我们已经为您准备了一个骨架应用程序,但是请更改您想要的任何内容(CSS文件,HTML结构,JS结构... GET - : :获取要显示在活动Feed中的电话 GET - : //aircall-

    http请求吗,响应头,状态码

    HTTP客户程序(例如浏览器),向服务器发送请求的时候必须指明请求类型(一般是GET或者POST)。如有必要,客户程序还可以选择发送其他的请求头。 1. Accept:浏览器可接受的MIME类型。 2. Accept-Charset:浏览器可...

    CGI脚本入门学习--HTML格式

    目 录 CGI脚本是什么? CGI脚本 怎样工作的? 一个简单的例子 ... GET 和 POST URL 编码 问题 CGI 变量 解码程序 uncgi cgi-lib.pl 解码文件上传的输入 自己做 非解剖的头部脚本 总结

    HttpHelper万能框架V2.2

    大家好我是苏飞 , 我的HttpHelper类相信很多人都用过, HttpHelper可以非常方便的实现Http协议的GET和POST请求、自动识 别编码、无视证书、优化Cookie、可以很方便的设置Cookie,Header,证书,代理等问题, 编码...

    基于c开发的一个超轻量型 HTTP Server源码.zip

    取出 HTTP 请求中的 method (GET 或 POST) 和 url。对于 GET 方法,如果有携带参数,则 query_string 指针指向 url 中 ? 后面的 GET 参数。 格式化 url 到 path 数组,表示浏览器请求的服务器文件路径,在 tiny_...

    httpGetPost.zip

    C++ ws2_32封装http请求,支持http get、post、filedown,解决请求编码问题

    JSP中文乱码问题综述,中文乱码解决大全

    中文乱码解决大全,表单使用Post方式提交后接收到的乱码问题,表单get提交方式的乱码处理方式,上传文件时的乱码解决,Java代码关于url请求,接受参数的乱码,关于jsp在MyEclipse中打开的乱码问题,关于html页面在eclipse...

    html入门到放弃笔记

    作用:保留源文档中的回车 和 空格 的作用 &lt;pre&gt;&lt;/pre&gt; 8、分区元素 1、块分区元素 语法:&lt;div&gt;&lt;/div&gt; 作用:布局 2、行内分区元素 语法:&lt;span&gt;&lt;/span&gt; 作用:设置同一行文字内的不同样式 9、行内元素 与...

    VB免控件实现HTTP请求程序源码

    【工控老马出品,必属精品...源码说明:无需任何OCX或DLL控件,直接调用windows内置对象实现HTTP请求,支持GET/POST等各种请求方法。返回HTML支持常见编码处理,避免中文乱码。 适合人群:新手及有一定经验的开发人员

    解决flask接口返回的内容中文乱码的问题

    写一个简单的例子程序: ...@app.route("/api", methods=["GET", "POST"]) def api(): if request.method == 'GET': return jsonify({"login status": "成功1"}) elif request.method == "POST": data = reques

Global site tag (gtag.js) - Google Analytics