客户端编码与服务器解码全过程

form有2中方法把数据提交给服务器,get和post,分别说下吧。 
(一)get提交 
  1.首先说下客户端(浏览器)的form表单用get方法是如何将数据编码后提交给服务器端的吧。 
   
    对于get方法来说,都是把数据串联在请求的url后面作为参数,如:http://localhost:8080/servlet?msg=abc 
(很常见的一个乱码问题就要出现了,如果url中出现中文或其它特殊字符的话,如:http://localhost:8080/servlet?msg=杭州,服务器端容易得到乱码),url拼接完成后,浏览器会对url进行URL encode,然后发送给服务器,URL encode的过程就是把部分url做为字符,按照某种编码方式(如:utf-8,gbk等)编码成二进制的字节码,然后每个字节用一个包含3个字符的字符串 "%xy" 表示,其中xy为该字节的两位十六进制表示形式。我这里说的可能不清楚,具体介绍可以看下java.NET.URLEncoder类的介绍在这里。了解了URL encode的过程,我们能看到2个很重要的问题,第一:需要URL encode的字符一般都是非ASCII的字符(笼统的讲),再通俗的讲就是除了英文字母以外的文字(如:中文,日文等)都要进行URL encode,所以对于我们来说,都是英文字母的url不会出现服务器得到乱码问题,出现乱码都是url里面带了中文或特殊字符造成的;第二:URL encode到底按照那种编码方式对字符编码?这里就是浏览器的事情了,而且不同的浏览器有不同的做法,中文版的浏览器一般会默认的使用GBK,通过设置浏览器也可以使用UTF-8,可能不同的用户就有不同的浏览器设置,也就造成不同的编码方式,所以很多网站的做法都是先把url里面的中文或特殊字符用JavaScript做URL encode,然后再拼接url提交数据,也就是替浏览器做了URL encode,好处就是网站可以统一get方法提交数据的编码方式。 完成了URL encode,那么现在的url就成了ASCII范围内的字符了,然后以iso-8859-1的编码方式转换成二进制随着请求头一起发送出去。这里想多说几句的是,对于get方法来说,没有请求实体,含有数据的url都在请求头里面,之所以用URL encode,我个人觉的原因是:对于请求头来说最终都是要用iso-8859-1编码方式编码成二进制的101010.....的纯数据在互联网上传送,如果直接将含有中文等特殊字符做iso-8859-1编码会丢失信息,所以先做URL encode是有必要的。 
   2。服务器端(tomcat)是如何将数据获取到进行解码的。 
   第一步是先把数据用iso-8859-1进行解码,对于get方法来说,tomcat获取数据的是ASCII范围内的请求头字符,其中的请求url里面带有参数数据,如果参数中有中文等特殊字符,那么目前还是URL encode后的%XY状态,先停下,我们先说下开发人员一般获取数据的过程。通常大家都是request.getParameter("name")获取参数数据,我们在request对象或得的数据都是经过解码过的,而解码过程中程序里是无法指定,这里要说下,有很多新手说用request.setCharacterEncoding("字符集")可以指定解码方式,其实是不可以的,看servlet的官方API说明有对此方法的解释:Overrides the name of the character encoding used in the body of this request. This method must be called prior to reading request parameters or reading input using getReader().可以看出对于get方法他是无能为力的。那么到底用什么编码方式解码数据的呢,这是tomcat的事情了,默认缺省用的是iso-8859-1,这样我们就能找到为什么get请求带中文参数为什么在服务器端得到乱码了,原因是在客户端一般都是用UTF-8或GBK对数据URL encode,这里用iso-8859-1方式URL decoder显然不行,在程序里我们可以直接

Java代码 

  1. new String(request.getParameter("name").getBytes("iso-8859-1"),"客户端指定的URL encode编码方式")

[java] view plain copy

  1. new String(request.getParameter("name").getBytes("iso-8859-1"),"客户端指定的URL encode编码方式")

还原回字节码,然后用正确的方式解码数据,网上的文章通常是在tomcat里面做个配置

Xml代码 

  1. <Connector port="8080" protocol="HTTP/1.1" maxThreads="150" connectionTimeout="20000" redirectPort="8443" URIEncoding="GBK"/>

[xml] view plain copy

  1. <Connector port="8080" protocol="HTTP/1.1" maxThreads="150" connectionTimeout="20000" redirectPort="8443" URIEncoding="GBK"/>

这样是让tomcat在获取数据后用指定的方式URL decoder,URL decoder的介绍在这里

(一)post提交 
1.客户端(浏览器)的form表单用post方法是如何将数据编码后提交给服务器端的。 
  在post方法里所要传送的数据也要URL encode,那么他是用什么编码方式的呢? 
   在form所在的html文件里如果有段<meta http-equiv="Content-Type" content="text/html; charset=字符集(GBK,utf-8等)"/>,那么post就会用此处指定的编码方式编码。一般大家都认为这段代码是为了让浏览器知道用什么字符集来对网页解释,所以网站都会把它放在html代码的最前端,尽量不出现乱码,其实它还有个作用就是指定form表单的post方法提交数据的URL encode编码方式。从这里可以看出对于get方法来数,浏览器对数据的URL encode的编码方式是有浏览器设置来决定,(可以用js做统一指定),而post方法,开发人员可以指定。 
2。服务器端(tomcat)是如何将数据获取到进行解码的。 
如果用tomcat默认缺省设置,也没做过滤器等编码设置,那么他也是用iso-8859-1解码的,但是request.setCharacterEncoding("字符集")可以派上用场。

我发现上面说的tomcat所做的事情前提都是在请求头里没有指定编码方式,如果请求头里指定了编码方式将按照这种方式编码。 
   有2篇文章推荐下,地址分别是 
http://www.cnblogs.com/yencain/articles/1321386.html; 
http://wanghuan8086.javaeye.com/blog/173869

时间: 2024-10-24 13:53:39

客户端编码与服务器解码全过程的相关文章

解如何利用 XML 和 JavaScript Object Notation 在 Ajax 客户端和 Java 服务器之间传输数据。

2006 年 6 月发表 Ajax 核心 API(即所谓的 XMLHttpRequest)的唯一用途就是发送 HTTP 请求,在 Web 浏览器与服务器之间进行数据交换.Web 页面中运行的 JavaScript 代码,可以使用 XMLHttpRequest 将该请求参数提交至服务器端脚本,例如 Servlet 或 JSP 页面.调用的 Servlet/JSP 将发回一个响应,其中包含了一般用于不需刷新整个页面即可更新用户查看内容的数据.此种方法在性能和可用性方面均体现出了独有的优势,因为这将降

TCP 同步传输:客户端发送,服务器段接收

1.服务器端程序 可以在TcpClient上调用GetStream()方法来获的链接到远程计算机的网络流NetworkStream.当在客户端调用时,他获的链接服务器端的流:当在服务器端调用时,他获得链接客户端的流. class Program { static void Main(string[] args) { const int BufferSize = 8192;//缓存大小 Console.WriteLine("server is running ..."); IPAddre

Android客户端与PC服务器通过socket进行交互实例(转)

一直以来对Android socket通信都很模糊,今天终于研究了一个网上的例子,自己又修改了下,算是对Android socket通信有点了解了. 下面是具体的代码,说明都在注释中了.需要注意的是,只有客户端发送了信息给服务器后,服务器才能响应客户端的输入,然后返回信息给客户端,这是客户端才能读取服务器返回的信息.如果客户端和服务器都处于等待对方的信息,那样就会造成阻塞,导致ANR了. 1.服务器端代码,就是一个java程序,与android无关,运行于服务器上,即PC机上. [java] v

解决连接vcenter (客户端无法向服务器发送完整的请求。(基础连接已经关闭:发送时发生错误。)) 问题

vCenter版本 5.5 vCenter 安装在server 2008 r2上面,今天补丁一打,重启后就无法连接vcenter了,起初以为是补丁的问题导致vcenter工作不正常,卸载了补丁依旧无法正常连接. 报未知连接错误,(客户端无法向服务器发送完整的请求.(基础连接已经关闭:发送时发生错误.)) 服务里面 vmware Virtualcenter server 服务启动不了. 倒腾了很久,, 很久   ,,    重装vcenter server 5.5的时候提示 vcenter 443

socket + pcntl_fork 实现客户端请求,服务器实时监听返回处理 消息推送

<?php /* socket链接整个过程 1,socket_create 第一个参数指定应用程序使用的通信协议的协议族,对于TCP/IP协议族,该参数置AF_INET: 第二个参数指定要创建的套接字类型,流套接字类型为SOCK_STREAM.数据报套接字类型为SOCK_DGRAM.原始套接字SOCK_RAW(WinSock接口并不适用某种特定的协议去封装它,而是由程序自行处理数据包以及协议首部): 第三个参数指定应用程序所使用的通信协议.此参数可以指定单个协议系列中的不同传输协议.在Inter

客户端本地到服务器丢包的检查方法

如果用户本地到服务器出现ping丢包或直接无法连接的时候,可以通过如下步骤进行排查分析:   客户端本地到服务器丢包的检查方法 1. ping服务器IP地址或域名,查看丢包情况:     ping 140.205.140.234 -n 100  说明: -n 后面的数字表示要进行的ping测试次数: 主要关注如下下图所示所统计的丢包率和平均超时时间: 2. 使用MTR工具跟踪下到服务器的链路情况: Windows下,使用所示的WinMTR工具进行跟踪测试: 用法:打开软件后,在[hosts]框中

服务器和客户端同步状态,客户端不能依赖服务器的响应

有一类系统,基本上所有操作都要求在线.在客户端产生的数据,直接提交到服务器,本地不存数据,或者仅保存少量缓存数据.这类应用有一个优势,就是客户端和服务器的数据始终是同步的,罕有两端不一致的情况.但是也有缺点,即对网络条件要求高,在网络条件不好的时候,用户操作需要等待,甚至无法正常使用 我们的一个APP,与上述系统不同,是支持离线操作的.数据在本地和服务器各有一份,然后通过同步机制来保持一致.这样做的缺点是提升了系统的复杂性,因为如果设计有缺陷,就很容易发生两端数据不一致的情况:另外就是如果客户端

3389爆破服务器技术全过程与原理

其实爆破服务器很简单的,也是必学的. 3389是一个远程桌面的端口,很多人为了更方便管理服务器,更新服务器上的资源等,经常会开启3389端口,用nastat-an命令可以查看该端口的开启.对于一个账户如果账号密码过于弱很容易被爆破到,一般默认账号为Administrator或admin,而对于过于简单的密码,在3389密码字典中均可找到,下面来讲解爆破3389服务器,获得一台服务器的全过程. 工具:DUbrute爆破工具(或者用frdpb)SYN扫描工具IP Search 首先用IPseache

Linux客户端访问Nginx服务器出现Cannot assign requested address错误

故障描述 参考文章 http://blog.csdn.net/sctq8888/article/details/7381910 不过这篇文章中提到的开启TIME-WAIT sockets的快速回收和重用功能可能在某些场景下会导致问题,比如使用NAT方式访问服务器时,由于很多客户端的出口IP都是一样的,由于TCP时间戳的不一致会导致在同一个WIFI下有的客户端可以访问,有的客户端不可以访问的现象. 参见http://john88wang.blog.51cto.com/2165294/1422705