`
wangyanlong0107
  • 浏览: 499861 次
  • 性别: Icon_minigender_1
  • 来自: 沈阳
社区版块
存档分类
最新评论

Http协议的编码

    博客分类:
  • http
 
阅读更多

用Get方式传中文参数存在很多问题!一不小心就会造成服务器收到的是乱码!所以一般情况下,都是尽量使用Post方法实现中文参数的传参。但是有的时候会出现意料之外的情况不得不用Get方法。解决方法有很多:

  1. 使用Javascript(encodeURI/encodeURIComponent函数)对URI或参数进行UTF-8编码,然后在服务器端解码
  2. 不使用Get头部存放参数,而是用实体部分存放参数(对于Java servlet来说可以,其他情况不知道。因为一般情况Get方法的Http通讯只有头部没有实体。所以此方法有局限性,Javascript实现不了)
  3. 使用Post(与之前说的一样,有特殊情况用不了Post,如用js直接打开一个url并下载其内容)

接下来详细解释下其中原委!

为什么中文会乱码?

这要从Http协议开始说起。Http通讯协议分为头部、实体两个部分。实体部分是可选的,如Get方法就不一定需要。当返回Get的请求时,实体部分的编码是根据头部中的content的值决定的。例如:Content-Type:text/html; charset=UTF-8这就设定了实体的编码为utf-8格式。

  • Post方式的请求参数是放在实体部分中的;
  • 使用Javascript进行Post传参时,实体部分的编码是根据所在文档的编码进行编码;
  • Get方式的请求参数是放在头部的ur中;
  • 使用Javascript进行Get传参时,头部的编码只支持ASCII字符集。所以浏览器会对URI进行编码。

对于get方法来说,都是把数据串联在请求的url后面作为参数,url拼接完成后,浏览器会对url进行URI encode,然后发送给服务器。URI encode的过程就是把部分的url做为字符,按照某种编码方式(如:utf-8,gbk等,各浏览器不同)编码成二进制的字节码,然后每个字节用一个包含3个字符的字符串 “%xy” 表示,其中xy为该字节的两位十六进制表示形式。另外也会将空格替换成”+”。详细过程可以参看JDK源码中的URIEncode类的实现。

可以看到“各浏览器的编码不同”且用户可以自己设置默认编码,这导致了很多不同可能。这也就是为什么IE可以firefox乱码,这个机器可以另一台机器乱码的根源。你无法确定不同的浏览器是使用了什么编码对URI中的非ASCII字符进行编码(ascII可读字符不编码)的,所以你无法在服务器是确定自己使用什么解码。更要命的是不同的服务器也有自己默认的解码。例如Tomcat的解码格式为ISO-8859-1(可以修改server.xml修改)。

如何实现更通用的解决方案?

在开篇时一共提到了三个解决方案,第二三种因为将参数放到了实体部分所以很安全放心,这两种编码你可以通过程序方便的控制。但它们都有局限性不能作为通用方案。所以第一种方案最可行。

具体的步骤:

  1. 浏览器端使用encodeURI对URI进行编码两次
  2. 服务器端使用URI decode(UTF-8)解码一次(Java:URIDecode.decode(“参数”,”utf-8″);)

首先了解下encodeURI与encodeURIComponent函数

encodeURI与encodeURIComponent都是将字符串进行URI encode(都使用utf-8编码),过程之前已经提到过了,但是有所区别。encodeURI有以下字符不会被编码:“!@#$&*()=:/;?+”,另外encodeURIComponent方法有以下字符不会被编码:“!*()”。浏览器的默认URI encode则是所有ASCII字符不会被编码。

为什么编码两次,解码一次呢?

首先浏览器只会对非ASCII字符进行编码,所以在经过两次或一次encodeURI编码之后,浏览器的编码不会起作用。那为什么要进行两次编码呢?

因为不确定服务器端是使用何种编码进行URI的解码。当然如果你很确信你使用的平台是固定的那就不需要了。如果想要代码跨平台则需要考虑。光这么将不够直接,看下的过程(假设服务器为Tomcat):

“中文”  ==encodeURI==>  ”%E4%B8%AD%E6%96%87″  ==encodeURI(%被编码)==>  ”%25E4%25B8%25AD%25E6%2596%2587″   ==Tomcat解码(ISO-8859-1)==>    ”%E4%B8%AD%E6%96%87″ ==Java decode(UTF-8)==>  ”中文”

可以看到进行了两次utf-8编码,一次ISO-8859-1解码,一次utf-8解码。因为ISO-8859-1与utf-8都包含了ASCII字符集(%属于其中之一),所以不会出现乱码。

jQuery中的陷阱

在使用jQuery中进行ajax操作时,我们只在浏览器端编码一次,然后在服务器端手动解码一次即可,为什么呢?

因为jQuery在ajax操作时,默认进行了一次编码:

function add( key, value ){
    s[ s.length ] = encodeURIComponent(key) + '=' + encodeURIComponent(value);
};

分享到:
评论

相关推荐

    HTTP协议的chunked编码

    Chunked编码是HTTP协议(特别是HTTP/1.1版本)中的一种传输机制,它允许发送方将大响应体分块发送,而不是一次性发送完整个响应。这种编码方式尤其适用于那些在传输过程中大小未知或不断变化的数据流。 Chunked编码...

    mina仿qq聊天功能,自定义协议,协议的编码和解码详解,发送xml对象json,mina开发大全,详细api,mina心跳

    mina仿qq聊天功能,自定义协议,协议的编码和解码详解,发送xml对象json,mina开发大全,详细api ...mina开发的在线聊天工具,mina仿qq功能,mina自定义协议,可以仿http请求,mina心跳等技术大全,mina功能大揭密

    sip协议以及其编码标准

    总的来说,SIP协议及其编码标准是构建现代通信系统的重要基石,其灵活性和可扩展性使得它能够适应不断发展的网络通信需求。通过理解并掌握SIP协议,开发者和网络管理员能够更好地设计和维护高效的多媒体通信服务。

    基于http协议的自定义协议封装

    本文将深入探讨基于HTTP协议的自定义协议封装,特别是在使用XML作为数据载体时如何进行设计和实现。HTTP(超文本传输协议)是互联网上应用最为广泛的一种网络协议,它允许客户端(如浏览器)和服务器之间交换数据。...

    http协议中文版(http协议中文版)

    1. **无状态**:HTTP协议自身不维护连接状态,每次请求和响应都是独立的,服务器不会记住之前请求的信息。为了实现状态保持,开发者通常会使用Cookie或Session。 2. **简单快速**:设计时主要考虑快速传输,对数据...

    VC 构造http协议数据的post上传图片类(MFC环境 带编码转换)模拟表单提交

    总之,VC++ MFC环境下构建的HTTP POST上传图片类需要处理的关键技术包括HTTP协议的理解、MFC类库的使用、文件读取与编码转换,以及模拟表单提交的逻辑。通过这样的实现,我们可以实现与Web表单类似的文件上传功能,...

    HTTP协议详解及RFC2616(HTTP)中文版

    HTTP/1.1是HTTP协议的一个重要版本,相比之前的HTTP/1.0,它引入了许多改进和新特性,如持久连接、分块传输编码和更多请求方法(如PUT、DELETE)。 **HTTP请求方法** HTTP协议定义了多种请求方法,常见的有GET、...

    HTTP协议在嵌入式系统中的实现

    HTTP协议,全称为超文本传输协议(Hypertext Transfer Protocol),是应用层的网络协议,用于实现访问网页的应用程序。在嵌入式系统中,特别是个人数字助理(PDA)等小型设备中实现HTTP协议的接入,对于扩展其网络...

    深入了解http协议

    HTTP(超文本传输协议)是互联网上应用最为广泛的一种网络协议,它定义...HTTP协议的深入学习还包括请求方法、状态码、头部字段、缓存策略、分块传输编码等多个方面,这些都是构建高效、安全的Web服务的关键组成部分。

    HTTP协议详解.pdf

    ### HTTP协议详解 #### 引言 HTTP,即超文本传输协议,自1990年提出以来,凭借其简洁高效的特点,迅速成为万维网(World Wide Web, WWW)中应用最为广泛的协议之一。HTTP协议最初的设计目标是提供一个简单、快速的...

    java实现http协议jar包

    Java实现HTTP协议的jar包是Java后端开发中常用的一种工具,它可以帮助开发者方便地进行HTTP请求的发送和处理响应。这些jar包包含了多种库,主要用于构建和执行HTTP客户端操作,如GET、POST等方法。以下是对每个jar包...

    语音识别(ASR)HTTP协议WebAPI开发文档1

    【语音识别(ASR)HTTP协议WebAPI开发文档1】主要介绍了如何利用HTTP协议实现语音识别功能,适用于开发者集成到各类应用中。该服务由北京大牛儿科技发展有限公司提供,具有轻量、跨平台、跨开发语言的优势。 **接口...

    HTTP协议详解PDF可打印版RFC2616

    **HTTP协议详解** HTTP(Hypertext Transfer Protocol)是互联网上应用最为广泛的一种网络协议,它是万维网(WWW)的基础,使得用户能够通过浏览器访问和交换信息。RFC2616是HTTP/1.1版本的官方规范文档,详细定义...

    HTTP.zip_C http协议_HTTP协议_c语言 http_c语言 http_c语言http协议

    HTTP协议是互联网上应用最为广泛的一种网络协议,用于从Web服务器传输超文本到本地浏览器的传输协议。它是一个基于请求与响应模型的、无状态的、应用层协议。本实例将深入探讨如何使用C语言来实现HTTP协议。 首先,...

    http协议详解(含中英文两版电子书)

    本资源包含HTTP协议的中英文双语版电子书,对于学习和理解HTTP协议具有极大的帮助。 HTTP协议的基础是请求-响应模型。当用户在浏览器中输入URL并按下回车键时,浏览器会向服务器发送一个HTTP请求。请求由三部分组成...

    http 协议分析代码实例

    5. **编码处理**:HTTP协议允许对传输的数据进行编码,如gzip压缩。解析代码需要能够识别并解码这些编码。 6. **分块传输**:在HTTP 1.1中,大文件可以通过分块传输来提高效率。解析代码应能处理接收到的数据块,并...

    DAHUA大华摄像头HTTP协议API

    标题中的“DAHUA大华摄像头HTTP协议API”意味着文档提供的是大华品牌摄像头产品通过HTTP协议交互的API(应用程序编程接口)的详细说明。文档属于版本1.0,意味着这是API规范的初始版或者是某个产品的特定版本。由于...

    人脸识别一体机HTTP接口协议_v1.34.pdf

    人脸识别一体机HTTP接口协议_v1.34是基于HTTP协议的接口协议,旨在提供人脸识别一体机设备与外部系统之间的数据交互接口。该协议定义了人脸识别一体机设备的基本信息、身份认证、音频设置、开门条件等多个方面的数据...

    http协议RFC中文版

    **HTTP协议概述** HTTP(Hypertext Transfer Protocol)是一种应用层协议,它是互联网上应用最为广泛的一种网络协议,用于从万维网服务器传输超文本到本地浏览器的传输协议。HTTP协议是基于TCP/IP协议的,它定义了...

Global site tag (gtag.js) - Google Analytics