`
twh1224
  • 浏览: 95546 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

关于GET和POST请求的编解码问题

阅读更多
转载  关于GET和POST请求的编解码问题 收藏

深入浅出URL编码

http://blog.csdn.net/yzhz  杨争 


一、问题:
        编码问题是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的字符集采用相同的字符集,这样程序的实现就很简单,不用做复杂的编码转换。
分享到:
评论

相关推荐

    解决boa服务器get/post请求中文乱码问题

    本主题聚焦于"boa服务器get/post请求中文乱码问题",并提及了sqlite3数据库处理中文乱码的情况。以下将详细介绍这两个方面的知识点。 1. Boa服务器与HTTP请求中文乱码: Boa服务器是一个轻量级的Web服务器,适用于...

    解决了中文乱码的http的get和post请求demo

    本篇将详细讲解如何处理中文乱码问题,特别是在HTTP的GET和POST请求中。参考文档来源于CSDN博主的文章,我们将围绕这个主题进行深入探讨。 首先,我们需要理解中文乱码问题产生的原因。当HTTP请求发送含有中文字符...

    android 后台 get和post请求数据

    总结,Android后台发送GET和POST请求主要涉及HTTP协议的使用、数据编码、网络请求库的选择以及异步处理。理解这些知识点对于开发能与服务器进行有效通信的Android应用至关重要。在处理过程中,要注意数据的安全性和...

    get、post请求中文乱码处理方式一

    本文将详细阐述GET和POST请求中文乱码的处理方式,以帮助开发者解决这类问题。 首先,我们需要了解为什么会出现中文乱码。在HTTP请求中,数据通常是按照ASCII编码进行传输的,而中文字符通常使用UTF-8或其他多字节...

    http请求工具类HttpClientUtil,get,post请求(csdn)————程序.pdf

    HttpClientUtil 是一个用于发送 HTTP 请求的工具类,主要支持 GET 和 POST 方法。它使用了 Apache HttpClient 库,这是一个强大的 Java 客户端编程工具包,用于处理 HTTP 协议。以下是对类中关键方法和概念的详细...

    服务器端测试GET、POST

    总结来说,理解GET和POST请求的工作原理,以及如何处理中文乱码问题,对于开发和测试服务器端功能至关重要。这涉及到HTTP协议、字符编码、客户端与服务器之间的交互,以及测试策略等多个方面,都是IT专业人士必备的...

    VBS的函数集-读写二进制文件,UTF8文件,HTTP GET和POST

    本资源是一个VBS函数集,提供了一系列功能强大且实用的函数,涉及到二进制文件读写、UTF-8文件读写、HTTP GET请求、HTTP POST请求、Base64编码解码等功能。下面是对该资源的详细解释和知识点总结: 一、基本概念 *...

    完美解决Get和Post请求中文乱码的问题

    总结,解决GET和POST请求中文乱码问题的关键在于明确编码格式,并在适当的地方进行编码和解码操作。在处理POST请求时,确保调用`setCharacterEncoding`方法;处理GET请求时,需要手动对URL参数进行解码。同时,配置...

    get、post区别

    - **POST**:通常不可缓存,多次相同的POST请求可能会有不同结果,例如,多次提交表单可能造成多次记录的创建。 ### GET与POST在实践中的应用 #### GET的应用场景 - 获取资源,如查询数据、下载文件等。 - 不涉及...

    get和post的区别

    - Tomcat同样默认使用ISO-8859-1编码解码POST请求中的参数。 - 可以通过`request.setCharacterEncoding("UTF-8")`设置编码,但这必须在调用任何获取参数的方法之前完成。 - 如果使用了`Content-Type`指定字符集,...

    java后端请求HTTP需要用到的jar包及其测试方法(get和post)

    **POST请求**: 1. 创建HttpClient实例。 2. 创建HttpPost请求对象,设置请求URL。 3. 创建NameValuePair列表,添加POST参数。 4. 使用HttpEntityEnclosingRequestBase的setEntity方法设置请求实体。 5. 发送请求并...

    HarmonyOS @ohos.net.http 网络GET、POST请求封装

    在 HarmonyOS 操作系统中,网络通信是应用开发不可或缺的一部分,@ohos.net.http 包提供了对 HTTP 协议的支持,使得开发者可以方便地进行 GET 和 POST 请求的封装。本篇将详细介绍如何利用这些功能来实现高效且可靠...

    中文乱码过滤器(包括GET和POST)

    2. 请求参数编码问题:GET和POST请求在传递参数时,如果没有正确设置字符编码,中文字符可能会被错误地编码为字节流,导致接收端解码失败。 3. 页面编码设置错误:网页的编码设置如果不正确,展示的中文字符也可能...

    Java中解决POST和GET请求的中文乱码问题.doc

    1. **表单页面设置**:与POST请求相同,GET请求的表单页面也需要设置字符集为UTF-8。 2. **服务器端获取参数**:GET请求的参数包含在URL中,服务器在获取这些参数时需要特殊处理。因为Servlet默认使用ISO-8859-1...

    post和get提交乱码处理

    POST请求通常用于向服务器发送大量数据或修改服务器资源,而GET请求则用于获取信息,其参数包含在URL中。由于GET请求的数据是可见的,所以在处理中文字符时更容易出现乱码问题。 乱码的产生主要是因为字符集不一致...

    C# url post get json

    2. **POST请求**: - 创建一个`HttpContent`对象,包装要发送的数据。对于JSON,可以使用`StringContent`,如`var content = new StringContent(json, Encoding.UTF8, "application/json");` - 调用`PostAsync`,...

    java发送get请求和post请求示例

    本文将详细介绍如何使用Java发送GET和POST请求,以及相应的示例代码。 ### GET请求 GET请求是最简单的HTTP请求方法,通常用于获取资源。它将参数附加到URL上,通过URL编码的方式传递。以下是一个使用Java发送GET...

    java乱码综合解决方法(不区分get和post)

    GET和POST请求的参数可能携带非ASCII字符,如果编码不一致,就会导致乱码。解决方法是确保服务器和客户端对请求参数的编码和解码使用相同的字符集。 2. **文件读写**:Java在读取或写入文件时,如果没有指定正确的...

    网络发包工具 POST/GET

    POST请求可以传输大量数据,如文件上传、数据库插入等,而且请求参数不会显示在URL上,更安全。 **GET方法**则是用来从服务器获取资源的,它将请求参数附加到URL后面,以问号(?)分隔。GET请求的数据量有限,一般...

    post参数加密请求.rar

    与GET请求不同,POST请求的数据不包含在URL中,而是放在请求体里,这使得POST请求能传输大量或敏感数据。 在Java中,处理POST请求时的加密通常涉及到以下几个关键技术: 1. **Base64编码**:在"javapostbase64"这...

Global site tag (gtag.js) - Google Analytics