`
wangyanlong0107
  • 浏览: 480184 次
  • 性别: 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编码

    HTTP协议的chunked编码

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

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

    高德地图API POI分类编码表

    高德地图 API POI 分类编码表,地理编码/逆地理编码 API 是通过 HTTP/HTTPS 协议访问远程服务的接口,提供结构化地址与经纬度之间的相互转化的能力。 结构化地址的定义: 首先,地址肯定是一串字符,内含国家、省份...

    对chunked编码进行解码

    一个对chunked编码进行解码的例子,通过java socket实现发送http请求,对gzip压缩的消息体进行解码处理。

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

    用VC写了个MFC环境下的post数据类这次将这个类进行扩展,可以post图片。但这两个post所使用的方法不一样。

    HTTP协议详解

    超 文本传输协议(HTTP)是一种为分布式,合作式,超媒体信息系统。它是一种通用的,无状态(stateless)的协议,除了应用于超文本传输外,它也 可以应用于诸如名称服务器和分布对象管理系统之类的系统,这可以通过...

    TCPIP协议详解卷三:TCP事务协议,HTTP,NNTP和UNIX域协议

    《TCP/IP详解·卷3:TCP事务协议、HTTP、NNTP和UNIX域协议》是“TCP/IP详解系列”的延续。主要内容包括:TCP事务协议,即T/TCP,这是对TCP的扩展,使客户-服务器事务更快、更高效和更可靠;TCP/IP应用,主要是HTTP和...

    短信中英文PDU编码,完整版,下载即用

    (转换地址)http://tool.chinaz.com/tools/unicode.aspx index -- 读取序号,在读取时用到 ******************* /*使用方式: size_sms = gsmEncodePdu(psms,temp); sprintf(GSMSMS_buff,"AT+CMGS=%d",size_sms); ...

    SOAP协议中文版

    一个作为描述在消息中的内容以及如何处理消息的信息框架的信封(envelope),一组用于表示应用定义的数据类型的编码规则(encoding rules),一个用于表示远程过程调用和返回的约定以及一个使用底层协议进行消息交换的...

    HTTP协议分析工具(HttpAnalyist)

    HTTP协议分析工具(HttpAnalyist),用于http/wap协议的分析,软件本身支持http/wap协议的发送,支持get 数据或post 文本,文件/文本+文件,支持实时修改cookies,UTF/base编码转换等,软件有误报,请放心使用

    c# http协议,实现get或post发送请求 并返回内容

    c# http协议,实现get或post发送请求 并返回内容

    TCP/IP详解 卷3:TCP事务协议、HTTP、NNTP和UNIX域协议

    16.4 编码举例 16.5 小结 第17章 Unix域协议:实现 17.1 概述 17.2 代码介绍 17.3 Unix domain和protosw结构 17.4 Unix域插口地址结构 17.5 Unix域协议控制块 17.6 uipc_usrreq函数 17.7 PRU_ATTACH请求和unp_attach...

    Delphi网络通信协议分析与应用实现pdf清晰

    4.1 HTTP协议基本知识 4.1.1 HTTP背景 4.1.2 HTTP的内容 4.1.3 消息(Message) 4.1.4 请求(Request) 4.1.5 响应(Response) 4.1.6 访问认证 4.1.7 URL编码 4.1.8 HTTP协议的应用 4.2 开发文件下载程序 4.2.1...

    Rtsp协议和数据解析Demo

    该协议提供的信息包括:时间戳(用于同步)、序列号(用于丢包和重排序检测)、以及负载格式(用于说明数据的编码格式)。 控制协议RTCP,用于QoS反馈和同步媒体流。相对于RTP来说,RTCP所占的带宽非常小; H.264和...

    SOAP协议规范(中文版).doc

    该SOAP协议规范,不是很完整,此中文文档只是帮助理解,内容并不详细!具体请参照英文文档!此文档目录如下: 目录 1. SOAP简介 2 1.1 SOAP1.2基本内容 2 1.2 符号约定 3 1.3 SOAP消息举例 3 2. SOAP消息交换模型 4 ...

    SDP协议规范

    他定义了绘画描述的统一格式,但并不定义多播地址的分配和SDP消息的传输,也不支持媒体编码方案的协商,这些功能均由下层传送协议完成.典型的会话传送协议包括:SAP(Session Announcement Protocol 会话公告协议),SIP,...

    H264视频编码器(H264encoder) v1.0.0.1 官方中文版.zip

    6、支持输出文件格式:FLV,MPEG-4,MPEG-2及HTTP,RTSP,UDP网络协议。 7、支持VBR及CBR压缩方式。 8、支持多种分辨率:FULL,D1等; 9、可将录制FLV格式文件再转换为MP4格式文件进行存储; 10、支持自动录制和...

    FFMPEG完美入门资料最新

    视音频在网络上传播的时候,常常采用各种流媒体协议,例如HTTP,RTMP,或是MMS等等。这些协议在传输视音频数据的同时,也会传输一些信令数据。这些信令数据包括对播放的控制(播放,暂停,停止),或者对网络状态的...

    易语言手机QQ协议精简

    易语言手机QQ协议精简源码,手机QQ协议精简,还原为字节集,取十进制,取验证码,登录,搜索客户,是否创建客户,删除已创建客户,置用户,连接,发送,标记,取指定内容,刷新客户端帐号,加入验证码,发送验证码,HTTP读文件_,...

    Java2网络协议技术内幕(源码)

    本书主要内容包括:internet基础,基础套接字,Telnet,FTP和TFTP,SMTP,P0P3,NNTP,HTTP,HTTPS等协议的网络通讯程序设计。内容系统全面,概念清晰,易于理解,每章都给出大量实例及分析... ...... ...

Global site tag (gtag.js) - Google Analytics