- 浏览: 1595517 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
jsrgzhangzhiyong:
关于null值的转换还是感觉不太友好,就像 mapstruct ...
我也造了个轮子:BeanMapping(属性拷贝) -
he037:
a417930422 写道引用使用EPHEMERAL会引出一个 ...
基于zookeeper的分布式lock实现 -
seancheer:
qianshangding 写道首先节点启动后,尝试读取本地的 ...
zookeeper学习记录三(session,watcher,persit机制) -
雪夜归人:
您好,我想咨询一下,开源的canal都能支持mysql的哪些版 ...
Canal BinlogChange(mysql5.6) -
zhoudengyun:
copy 一份做记录,后续学习,请知悉
阿里巴巴开源项目: 基于mysql数据库binlog的增量订阅&消费
问题起因:
客户订购了一关键字为"e+h
变送器"
, 在首页推荐广告中,会根据用户在search
搜索过的关键字进行一个匹配投放。技术实现是UED
通过JS
获取cookie
中的h_keys
内容,拼装到 http://xxxxx/advert/ctp_advert.htm?num=4&keyword=
{keyword}
。
这里取出来对应的cookie
信息为中文,最后通过一个ajax
发起一个GET请求。
所以针对最后的请求是:http://xxxxxx/advert/ctp_advert.htm?num=
4&keyword=e+h
变送器。 而在服务端接受到对应的请求参数时,发现参数为:e h
变送器, +
号没了。 初步怀疑跟URL规范相关,需要进行url encode
。
问题分析:
查了下JS encode
的相关内容, 总于发现+
号的秘密。
html
中因为一些非标准的做法,将+
等同于空格进行处理
(当Html
的表单被提交时, 每个表单域都会被Url
编码之后才在被发送。由于历史的原因,表单使用的Url
编码实现并不符合最新的标准。例如对于空格使用
的编码并不是%20
,而是+
号,如果表单使用的是Post
方法提交的,我们可以在HTTP
头中看到有一个Content-Type
的header
,值为 application/x-www-form-urlencoded
,大部分应用程序均能处理这种非标准实现的Url
编码)。
在搜索引擎中做了下尝试:
keyword = e h
变送器 , url =
http:
//www.google.cn/search?hl=zh-CN&newwindow=1&q=e+h变送器
(
空格被转化为+
号)
keyword = e+ h
变送器 , url = http:
//www.google.cn/search?hl=zh-CN&newwindow=1&q=e%2Bh变送器
(+
号被进行了转义为%2B
,程序才能正常处理)
问题解决:
思路1:
1.
要想正常传输+
号而不被转义为空格,需要进行进行编码为%2B
。查了下几个编码函数,发现只有encodeURIComponent
才会对+
号进行编码处理。
2. encodeURIComponent
默认为采用UTF-8
字符集,理论上只需要在原先的请求中添加_input_charset=utf-8(
由 pipeline
中的SetLocaleValve
进行解析)
,就可以得到正确的 e+h
变送器。
在实施过程中,发现结果并不是预期的那样。 客户端通过js encode
后,在服务端解析后一直是乱码。
查了下byte
,发现服务端一直是用GBK
在进行解析, 针对变送器的UTF-8
编码的byte
为{-27,-113,-104,-23,-128,-127}
,客户端用GBK
解析后变为{-27.-113.- 104.-23,-63,-63}
,针对最后两byte
因为字符不可见,导致全部被替换为-63
。网上查了下,针对 utf-8 -> gbk -> utf-8
在一定情况下就会出现该问题(http://lingqi1818.iteye.com/blog/348953
)
。
思路2
:
继续追查对应的_input_charset=utf-8
未生效的原因,DEBUG
看到在SetLocaleValve
中的确设置了 request.setCharsetEncoding
为utf-8
。初步怀疑是否跟jboss server
的配置有关,查了下跟URIEncoding
和useBodyEncodingForURI
设置有关。 目前公司所使用的jboss
为4.05
,对应俄tomact
配置中只指定了对应的URIEncoding=GBK
。正因为这样,导致设置的_input_charset
针对GBK
的提交没有效果
,还是按照GBK
进行解析。
1.
考虑将请求由GET
换成POST
, 这样就可以使用_input_charset
但在实施过程中,和UED
沟通过程,针对POST
的会引起一个跨域请求的问题。此方案又只能做罢
思路3
(
实践成功)
:
1. UED
进行伪url encode
的实现 ,
将+
号进行%2B
的编码。
因为目前JS
中没有现成的函数,这里只是通过replace(/\+/g,
'%2B')
进行了转化。
总
结
针对+
号的处理,针对不同的业务场景需要不同的处理方案,描述下几种场景:
1.
非Ajax
请求
可以直接使用Form
表单的 GET ,POST
的urlencode
协议,自动实现+ => %2B
的转化
2. Ajax
请求
* GET
请求 :
很无奈,只能使用方案3
,人为进行+
号转化。
* POST
请求(
同一应用,非跨域请 求) :
使用encodeURIComponent +
_input_charset=utf-8
指定编码进行处理。
ps:
前面提的这几种方案,都是基于+
号是正常的业务场景进行考虑。同时我们也可以从业务层面进行一个梳理,+
号处理是否有其必要性,能从业务数据入口直接规避 那就最好了。
背景知识:
URIEncoding
和useBodyEncodingForURI
对于URL
提交的数据和表单中GET
方式提交的数据,在接收数据的JSP
中设置request.setCharacterEncoding
参数是不行的, 因为在Tomcat5.0
中,默认情况下使用ISO- 8859-1
对URL
提交的数据和表单中GET
方式提交的数据进行重新编码(解码),而不使用该参数对URL
提交的数据和表单中GET
方式提交的数据进行 重新编码(解码)。要解决该问题,应该在Tomcat
的配置文件的Connector
标签中设置useBodyEncodingForURI
或者 URIEncoding
属性,其中useBodyEncodingForURI
参数表示是否用
request.setCharacterEncoding
参数对URL
提交的数据和表单中GET
方式提交的数据进行重新编码
,在默认情 况下,该参数为false
(Tomcat4.0
中该参数默认为true
); URIEncoding
参数
指定对所有GET
方式请求(包括URL
提交的数据和表单中GET
方式提交的数据)进行统一的重新编码(解码)的编码
。
URIEncoding
和useBodyEncodingForURI
区别是,URIEncoding
是对所有GET
方式的请求的数据进行统一的重新编码 (解码),而useBodyEncodingForURI
则是根据响应该请求的页面的request.setCharacterEncoding
参数对数
据进行的重新编码(解码),不同的页面可以有不同的重新编码(解码)的编码。所以对于URL
提交的数据和表单中GET
方式提交的数据,可以修改 URIEncoding
参数为浏览器编码或者修改useBodyEncodingForURI
为true
,并且在获得数据的JSP
页面中 request.setCharacterEncoding
参数设置成浏览器编码。
为什么需要Url
编码
1. Url
中有些字符会引起歧义 , =,&
号等
2. Url
的编码格式采用的是ASCII
码,而不是Unicode
,这也就是说你不能在Url
中包含任何非ASCII
字符,例如中文
哪些字符需要编码
RFC3986
文档规定,Url
中只允许包含英文字母(a-zA-Z
)、数字(0-9
)、-_.~4
个特殊字符以及所有保留字符。
Url
可以划分成若干个组件,协议、主机、路径等。RFC3986
中指定了以下字符为保留字符: ! * ' ( ) ; : @ & =
+
$ , / ? # [ ]
如何对Url
中的非法字符进行编码
Url
编码通常也被称为百分号编码(Url Encoding
,also
known as percent-encoding
),是因为它的编码方式非常简单,使用%
百分号加上两位的字符——0123456789ABCDEF——
代表一个字节的 十六进制形式。Url
编码默认使用的字符集是US-ASCII
。例如a
在US-ASCII
码中对应的字节是0x61
,那么Url
编码之后得到的就是%
61
,我们在地址栏上输入http:
//g.cn/search?q=%61%62%63,实际上就等同于在google
上搜索abc
了。又如@
符号在
ASCII
字符集中对应的字节为0x40
,经过Url
编码之后得到的是%40
。
Javascript
中的escape,encodeURI
和encodeURIComponent
的区别
Javascript
中提供了3
对函数用来对Url
编码以得到合法的Url
,它们分别是escape / unescape,encodeURI /
decodeURI
和encodeURIComponent / decodeURIComponent
。解码和编码的过程是可逆的.
兼容性不同
escape
函数是从Javascript1.0
的时候就存在了,其他两个函数是在Javascript1.5
才引入的。但是由于 Javascript1.5
已经非常普及了,所以实际上使用encodeURI
和encodeURIComponent
并不会有什么兼容性问题。
对Unicode
字符的编码方式不同
这三个函数对于ASCII
字符的编码方式相同,均是使用百分号+
两位十六进制字符来表示。但是对于Unicode
字符,escape
的编码方式是% uxxxx
,其中的xxxx
是用来表示unicode
字符的4
位十六进制字符。这种方式已经被W3C
废弃了。但是在ECMA-262
标准中仍然保留着 escape
的这种编码语法。encodeURI
和encodeURIComponent
则使用UTF-8
对非ASCII
字符进行编码,然后再进行百分号 编码。这是RFC
推荐的。因此建议尽可能的使用这两个函数替代escape
进行编码。
适用场合不同
encodeURI
被用作对一个完整的URI
进行编码,而encodeURIComponent
被用作对URI
的一个组件进行编码。
安全字符不同
escape
(69
个) */@+-._0-9a-zA-Z
encodeURI
(82
个)
!#$&'()*+,/:;=?@-._~0-9a-zA-Z
encodeURIComponent
(71
个)
!'()*-._~0-9a-zA-Z
(
注意+
号未在其安全字符里)
其他和Url
编码相关的问题
对于包含中文的Url
的处理问题,不同浏览器有不同的表现。例如对于IE
,如果你勾选了高级设置“
总是以UTF-8
发送Url”
,那么Url
中的路径部分 的中文会使用UTF-8
进行Url
编码之后发送给服务端,而查询参数中的中文部分使用系统默认字符集进行Url
编码。为了保证最大互操作性,建议所有放到 Url
中的组件全部显式指定某个字符集进行Url
编码,而不依赖于浏览器的默认实现。
另外,很多HTTP
监视工具或者浏览器地址栏等在显示Url
的时候会自动将Url
进行一次解码(使用UTF-8
字符集),这就是为什么当你在 Firefox
中访问Google
搜索中文的时候,地址栏显示的Url
包含中文的缘故。但实际上发送给服务端的原始Url
还是经过编码的。你可以在地址栏
上使用Javascript
访问location.href
就可以看出来了。在研究Url
编解码的时候千万别被这些假象给迷惑了。
评论
发表评论
-
yugong QuickStart
2016-03-05 01:52 0几点说明 a. 数据迁移的方案可参见设计文档,oracl ... -
阿里巴巴开源项目: 阿里巴巴去Oracle数据迁移同步工具
2016-03-05 18:29 6509背景 08年左右,阿里巴巴开始尝试MySQL的相关 ... -
愚公performance
2016-03-02 17:29 0性能测试 全量测试 场景1 (单主键, ... -
yugong AdminGuide
2016-03-02 16:40 0环境要求 操作系统 数据库 迁移方案 部署 ... -
Tddl_hint
2014-01-27 13:52 0背景 工作原理 Hint格式 direct模 ... -
tddl5分库规则
2014-01-26 14:41 0背景 工作原理 构建语法树 元数据 基于 ... -
tddl5优化器
2014-01-22 15:12 0背景 工作原理 构建语法树 元数据 抽象语 ... -
Canal BinlogChange(mariadb5/10)
2014-01-20 17:25 4587背景 先前开源了一个 ... -
asynload quickstart
2013-10-08 22:49 0几点说明: 1. asyncload是做为一个j ... -
网友文档贡献
2013-09-18 15:50 01. Otter源代码解析系列 链接:http://e ... -
Manager配置介绍
2013-09-16 13:00 0通道配置说明 多种同步方式配置 a. 单向同步 ... -
canal&otter FAQ
2013-09-05 17:30 0常见问题 1. canal和 ... -
阿里巴巴开源项目:分布式数据库同步系统otter(解决中美异地机房)
2013-08-22 16:48 40433项目背景 阿里巴巴B2B公司,因为业务的特性 ... -
Otter AdminGuide
2013-08-19 11:06 0几点说明 otter系统自带了manager,所以简化了一 ... -
Otter高可用性
2013-08-17 23:41 0基本需求 网络不可靠,异地机房尤为明显. man ... -
Otter数据一致性
2013-08-17 23:39 0技术选型分析 需要处理一致性的业务场景: 多地修改 ( ... -
Otter扩展性
2013-08-17 22:20 0扩展性定义 按照实现不同,可分为两类: 数据处理自定 ... -
Otter双向回环控制
2013-08-17 21:37 0基本需求 支持mysql/oracle的异构数据库的双 ... -
Otter调度模型
2013-08-17 20:13 0背景 在介绍调度模型之前,首先了解一下otter系统要解 ... -
Otter Manager介绍
2013-08-16 11:16 0背景 otter4.0发布至 ...
相关推荐
在URL中处理特殊字符是一个非常重要的知识点,特别是在Web开发中。URL(Uniform Resource Locator)是互联网上使用的资源标识符,用于标识互联网上的资源。但是,在URL中有些符号是不能直接传递的,如空格、加号、...
下面将详细解析在JavaScript中处理含有加号的参数的方法,并且讨论URL编码和Base64编码的使用场景。 首先,我们需要了解URL编码的基本规则。在URL中,除了字母、数字以及少数符号(-_.)之外,其它字符都需要被编码...
url出现了有+,空格,/,?,%,#,&,=等特殊符号的时候,可能在服务器端无法获得正确的参数值,...+ URL 中+号表示空格 + 空格 URL中的空格可以用+号或者编码 / 分隔目录和子目录 / ? 分隔实际的URL和参数
这是因为根据URL编码标准,加号 (+) 在URL中通常代表空格。例如,如果你有这样一个参数:`key=value+OK`,在传递到服务器时,未进行转义的“+”会被解释为空格,服务器收到的参数可能是`key=value OK`,而非预期的`...
1. **避免冲突**:当一个URL作为参数传递给另一个URL时,为了防止与目标URL中的参数产生冲突,需要对传递的URL进行编码。 2. **兼容性问题**:中文或者其他非ASCII字符在传输过程中可能会出现问题,对其进行编码...
在Android应用开发中,创建一个类似Qzone底部导航栏的加号弹出菜单是一个常见的需求。这个功能可以增强用户体验,使用户能够轻松访问更多功能或服务。本文将深入讲解如何实现这一设计,主要关注Android中的菜单视图...
标题中的“自动添加引号加号sql文处理利器”指的是一个专门用于简化SQL语句处理的工具,它能够帮助程序员自动完成SQL语句中的引号添加、加号连接等常见操作,极大地提高了编写和处理SQL语句的效率。在编程过程中,...
在Android开发中,为了实现类似知乎加号按钮的动画效果,我们需要借助于Android的Animation库,特别是`android.support.v7.widget`包中的某些组件和工具。这个加号按钮的动画通常涉及按钮的展开和收缩,这可以是通过...
在IT领域,尤其是在Web开发中,处理URL中的特殊字符编码是一项常见的需求。URL中的某些字符因为具有特殊含义或不被支持,会被转换为十六进制形式的百分号编码(Percent-Encoding),例如空格通常被编码为"%20",而...
在Android应用开发中,"仿Path加号效果菜单"是一种常见的设计模式,它借鉴了Path应用中的加号(+)菜单动画效果。这种特效通常用于显示更多操作选项,以一种吸引用户注意且交互性强的方式呈现。下面将详细介绍这种...
当处理大量图片时,性能优化至关重要。可以使用LruCache或DiskLruCache进行内存和磁盘缓存,减少不必要的IO操作。同时,对图片进行适当的缩放和裁剪,避免加载大图导致的内存溢出。 8. 数据持久化: 如果应用需要...
在互联网世界中,URL(统一资源定位符)...无论是前端还是后端,都需要关注URL中特殊符号的处理,以保证数据的完整性和正确性。通过遵循上述规则和使用合适的编码函数,我们可以有效解决URL参数中特殊符号带来的问题。
因此,POST请求不会对参数中的"+"或"&"进行特殊处理,从而可以避免加号变空格和参数分隔问题。但需要注意的是,POST请求可能会导致缓存问题,且通常不适用于幂等操作(即多次执行同一操作,结果始终相同的操作)。 ...
对于Python中处理URL编码的函数,urllib.parse模块中的quote函数是其中之一,它可以将一个字符串进行URL编码。例如,如果我们的URL中包含了中文,那么使用quote函数就可以将中文字符转换为URL编码。在quote函数中,...
由于中文字符在URL中需要特殊编码才能正确传输,因此这里主要介绍如何使用PHP处理中文URL,以及涉及到的编码转换技巧。 首先,让我们了解URL编码的基本原理。在URL中,非ASCII字符需要被转换为百分号编码(%xx)的...
URL编码主要涉及对URL中的特殊字符进行转换,以避免这些字符在传输过程中引起解析错误或产生歧义。 RFC3986是定义URI语法的官方标准,它规定了URL中哪些字符是安全的,哪些需要进行编码。安全字符包括英文字母(a-...
标题“初中语文文摘人生做别人生命中的加号”虽然主要针对初中语文的学习,但其蕴含的哲理适用于所有人,尤其是人际交往中的态度和行为。这段文字探讨的是如何在与他人交往的过程中,成为一个能为他人生活增添价值的...
在Java编程语言中,`URLDecoder`和`URLEncoder`是两个非常重要的工具类,主要用于处理URL中的中文字符和其他特殊字符。这两个类位于`java.net`包下,可以帮助开发者进行字符串编码和解码,确保数据在网络传输过程中...