JSwindow.open或者表单提交中⽂参数乱码
JS window.open或者表单提交中⽂参数乱码
⾸先,解决办法主要是在客户端对该参数进⾏编码,然后在服务端解码,⼀下说明两种途径。:
⼀:
客户端:param=encodeURI(encodeURI(param));
window.open(url+param);
服务端:String param=URLDecoder.decode(param,"UTF-8");
⼆:
客户端:param=encodeURI(param);
window.open(url+param);
服务端:String param=new Bytes( "iso-8859-1" ), "UTF-8" );
HTTP 协议和 GET, POST 的⼯作⽅式:
当⽤户在Web浏览器地址栏中输⼊⼀个带有前缀的URL并按下Enter后,或者在Web页⾯中某个以开头
的超链接上单击⿏标,HTTP事务处理的第⼀个阶段--建⽴连接阶段就开始了.HTTP的默认端⼝是80.
随着连接的建⽴,HTTP就进⼊了客户向服务器发送请求的阶段.客户向服务器发送的请求是⼀个有特定格式的ASCII消息,
其语法规则为:
< Method > < URL > < HTTP Version > <\n>
{ <Header>:<Value> <\n>}*
<\n>
{ Entity Body }
请求消息的顶端是请求⾏,⽤于指定⽅法,URL和HTTP协议的版本,请求⾏的最后是回车换⾏.⽅法有G
ET,POST,HEAD,PUT,DELETE等.在请求⾏之后是若⼲个报头(Header)⾏.每个报头⾏都是由⼀个报头和⼀个取值构成的⼆元对,报头和取值之间以":"分隔;
报头⾏的最后是回车换⾏. 常见的报头有Accept(指定MIME媒体类型),Accept_Charset(响应消息的编码⽅式),
Accept_Encoding(响应消息的字符集),User_Agent(⽤户的浏览器信息)等.
在请求消息的报头⾏之后是⼀个回车换⾏,表明请求消息的报头部分结束.在这个\n之后是请求消息的消息实体
(Entity Body).
Web服务器在收到客户请求并作出处理之后,要向客户发送应答消息.与请求消息⼀样,应答消息的语法规则为:
< HTTP Version> <Status Code> [<Message>]<\n>
{ <Header>:<Value> <\n> } *
<\n>
{ Entity Body }
应答消息的第⼀⾏为状态⾏,其中包括了HTTP版本号,状态码和对状态码进⾏简短解释的消息;状态⾏的最后是回车换⾏.
状态码由3位数字组成,有5类:
# 1XX 保留
# 2XX 表⽰成功
# 3XX 表⽰URL已经被移⾛
# 4XX 表⽰客户错误
# 5XX 表⽰服务器错误
例如:415,表⽰不⽀持改媒体类型;503,表⽰服务器不能访问.最常见的是200,表⽰成功.常见的报头有:Last_Modified
(最后修改时间),Content_Type(消息内容的MIME类型),Content_Length(内容长度)等.
在报头⾏之后也是⼀个回车换⾏,⽤以表⽰应答消息的报头部分的结束,以及应答消息实体的开始.
下⾯是⼀个应答消息的例⼦:
HTTP/1.0 200 OK
Date: Moday,07-Apr-97 21:13:02 GMT
Server:NCSA/1.1
MIME_Version:1.0
Content_Type:text/html
Last_Modified:Thu Dec 5 09:28:01 1996
Coentent_Length:3107
<HTML><HEAD><TITLE>...</HTML>
那么 GET 和 POST 有什么区别? 区别就是⼀个在 URL 请求⾥⾯附带了表单参数和值, ⼀个是在 HTTP 请求的消息实体中.
⽤下⾯的例⼦可以很容易的看到同样的数据通过GET和POST来发送的区别, 发送的数据是 username=张三 :
GET ⽅式, 浏览器键⼊ localhost?username=张三
url编码和utf8区别GET /?username=%E5%BC%A0%E4%B8%89 HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, */*
Accept-Language: zh-cn
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.1.4322)
Host: localhost
Connection: Keep-Alive
POST ⽅式:
POST / HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, */*
Accept-Language: zh-cn
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.1.4322)
Host: localhost
Content-Length: 28
Connection: Keep-Alive
username=%E5%BC%A0%E4%B8%89
⽐较⼀下上⾯的两段⽂字, 您会发现 GET ⽅式把表单内容放在前⾯的请求头中, ⽽ POST 则把这些内容放在请求的主
体中了, 同时 POST 中把请求的 Content-Type 头设置为 application/x-www-form-urlencoded. ⽽发送的正⽂都是⼀样的,
可以这样来构造⼀个表单提交正⽂:
encodeURIComponent(arg1)=encodeURIComponent(value1)&
encodeURIComponent(arg2)=encodeURIComponent(value2)&.....
注: encodeURIComponent 返回⼀个包含了 charstring 内容的新的 String 对象(Unicode 格式), 所有空格、标点、
重⾳符号以及其他⾮ ASCII 字符都⽤ %xx 编码代替,其中 xx 等于表⽰该字符的⼗六进制数。 例如,空格返回的是 "%20" 。
字符的值⼤于 255 的⽤ %uxxxx 格式存储。参见 JavaScript 的 encodeURIComponent() ⽅法.
GET⽅法参数如何提交(编码如何转换):
对于get⽅法来说,都是把数据串联在请求的url后⾯作为参数,如:
(很常见的⼀个乱码问题就要出现了,如果url中出现中⽂或其它特殊字符的话,如:=杭州,服务器端容易得到乱码),url拼接完成后,浏览器会对url进⾏URL encode,然后发送给服务器,URL encode的过程就是把部分url做为字符,按照某种编码⽅式(如:utf-8,gbk 等)编码成⼆进制的字节码,然后每个字节⽤⼀个包含3个字符的字符串 "%xy" 表⽰,其中xy为该字节的两位⼗六进制表⽰形式。我这⾥说的可能不清楚,具体介绍可以看下java.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编码⽅式编码成⼆进制的的纯数据在互联⽹上传送,如果直接将含有中⽂等特殊字符做iso-8859-1编码会丢失信息,所以先做URL encode是有必要的。
2。服务器端(tomcat)是如何将数据获取到进⾏解码的。
第⼀步是先把数据⽤iso-8859-1进⾏解码,对于get⽅法来说,tomcat获取数据的是ASCII范围内的请求头字符,其中的请求url⾥⾯带有参数数据,如果参数中有中⽂等特殊字符,那么⽬前还是URL encode后的%XY状态,先停下,我们先说下开发⼈员⼀般获取数据的过程。通常⼤家都是Parameter("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显然不⾏的
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论