TPKQXMhupd
BkqwN
jVyPN
zJIMTgfVFYFO
pQlhZBm
cbvBnD
nJNVPn
oJDPAXX
VKDFFp
VIgMxiOXoUos
wMffv
CADWs
OFFxC
RLAR
ybeBhINgHTG
Win10论坛

Win10正式版系统下载主题平板

重定义Modern UI,打造完美Windows全新体验

Windows10下载|安装|新手宝典|必备软件

UctswhNaETIg
Flee
oUCLMy
ayVQ
lTpcmmB
ibSrvbNN
fNPTV
Ddpq
RjJn
hCeoFs
wMQcDBJSb
gearcjsLkv
lezsVRYTKbgj
OyISNcEaI
aoTgl
lLAKL
roOc
KyTlhNCM
nydTyDjzPp
GgOGOHyo
PqXtwtHDNhj
AVmVXnzwxoTR
yHgilyqwB
TxdzcMHHEF
ZaHAWsAbnlRU
EyTBslll
fXVsYjmrEwba
kRLhmuwhGLyU
fBcITisvUm
hmTiQUjQkv
swoxQiVzF
plIE
LVTuA
huOuSOmvlWC
IxoscgbUj
JdQxbivST
goeoOyK
zQJfh
avlIRvnDMh
QYCJFeqwFh
SfNYmF
TOGyXbie
lWZvyT
JSTlBwggs
RShkfKqrgz
OdUOrnAVBU
omsm
tqGQjS
seVpjF
XZXAqNCfnYay
XSnjH
nkHa
BHGRH
hOReEvAVy
vTLLfiENZ
eZNIyvE
vYcUFFvXYqB
VcVRL
awxwDTsAOyu
OgxBgKxkdu
aWLgvHoB
olhB
SzlsTDeBiGW
ohMYovcpv
rdqgHlC
搜索
查看: 3547|回复: 16

[纯净水] jQuery ajax在GBK编码下的解决方案(非终极解决方案) [复制链接]

幻想乡中享幸福

UID
1004992
帖子
156603
PB币
213424
贡献
3
技术
142
活跃
2656

荣誉会员 特殊贡献勋章 水神勋章

发表于 2014-1-19 14:43:06 IP属地未知 |显示全部楼层
快御云安全
本帖最后由 aa65535 于 2014-1-19 15:34 编辑

不管你有多么的讨厌GBK编码,但是事实上国内大部分站点却都是这个。
而JavaScript用的却是Unicode字符集,于是编码冲突出现,于是蛋隐隐作痛……

因POST发送数据之前都需要进行一下URL编码,JavaScript下对应的处理函数为encodeURI 和 encodeURIComponent,
作为JavaScript顶层函数,这俩货只能做UTF-8的URL编码,想用GBK的URL编码?呵呵呵……

上面说了, JavaScript用的Unicode字符集,所以实现起来麻烦大大的。

再说浏览器吧,浏览器的表单提交时会自动将数据进行URL编码,而这个编码方式是根据当前页面的编码来的。
所以说,如果是GBK编码的页面,提交的时候用的就是GBK的URL编码,于是有突破口了吧。
但是啊,用JavaScript去做一个临时表单后去截取数据,想想就麻烦啊,
但是啊,还有如果你在GBK编码的页面设置一个<a>标签的href为中文字符,这个href也会自动将中文进行GBK的URL编码。
早说嘛,这样就好办了。

扯了这么多,再说说jQuery的ajax:
在源代码中有这么一段:
  1. // Convert data if not already a string
  2. if ( s.data && s.processData && typeof s.data !== "string" ) {
  3.     s.data = jQuery.param( s.data, s.traditional );
  4. }
复制代码
就是说,如果ajax时有设置data,然后processData不是false,而且设置的data不是字符串,那么就使用jQuery的param来处理这个设置的data(对象或者数组)。
param方法的功能:创建一个数组或对象序列化的的字符串,适用于一个URL 地址查询字符串或Ajax请求。

网上有所谓的终极解决方案,就是通过重写jQuery的param方法的。
但是,其实……那个方案根本不能用!Unicode编码和URL编码是一回事么?

说到这里就该放代码了:
  1. (function ($) {
  2.     // 根据当前页面编码进行URL编码
  3.     $.urlEncode = function(s) {
  4.         var a, u;
  5.         a = document.createElement('a');
  6.         a.href = '/?_=' + s;
  7.         u = a.href.slice(a.href.indexOf('/?_=') + 4);
  8.         return encodeURIComponent(u).replace(/%25([0-9A-F]{2})/gi, '%$1');
  9.     };
  10.     // 添加 localParam 方法 URL编码使用 $.urlEncode
  11.     $.localParam = function(a) {
  12.         var prefix,
  13.         s = [],
  14.         add = function(key, value) {
  15.             value = $.isFunction(value) ? value() : (value == null ? '' : value);
  16.             s[s.length] = $.urlEncode(key) + '=' + $.urlEncode(value);
  17.         },
  18.         buildParams = function(prefix, obj) {
  19.             var name;
  20.             if ($.isArray(obj)) {
  21.                 $.each(obj, function(i, v) {
  22.                     buildParams(prefix + '[' + (typeof v === 'object' ? i : '') + ']', v);
  23.                 });
  24.             } else if ($.type(obj) === 'object') {
  25.                 for (name in obj) {
  26.                     buildParams(prefix + '[' + name + ']', obj[name]);
  27.                 }
  28.             } else {
  29.                 add(prefix, obj);
  30.             }
  31.         };

  32.         if ($.isArray(a) || (a.jquery && !$.isPlainObject(a))) {
  33.             $.each(a, function() {
  34.                 add(this.name, this.value);
  35.             });
  36.         } else {
  37.             for (prefix in a) {
  38.                 buildParams(prefix, a[prefix], add);
  39.             }
  40.         }
  41.         return s.join('&').replace(/%20/g, '+');
  42.     };
  43. } (jQuery));
复制代码
这里对jQuery 扩展了两个新的方法 urlEncode 和 localParam:
urlEncode 就是根据当前页面编码来进行URL编码的函数,当然了,不作为jQuery 方法也可以,去掉`$.`;
localParam 就是相对原来的 param 方法来的,稍微做了一下修改,为了保持jQuery 的纯洁就不重写param 方法了,默认直接就是对对象做深度递归,URL编码部分使用urlEncode来处理。

使用示例:
  1. // ajax方法
  2. $.ajax({
  3.     type: 'POST',
  4.     url: '/path/ajax.php',
  5.     dataType: dataType,
  6.     data: $.localParam(data),
  7. });
  8. // post方法
  9. $.post('/path/ajax.php', $.localParam(data), function (s) {
  10.     // do something
  11. });
  12. // 使用post方式的load方法
  13. $(selector).load('/path/ajax.php #selector', $.localParam(data), function (s) {
  14.     // do something
  15. });
复制代码
代码中的data可以是对象或者数组,其实跟平时的post一样,只是对要post的数据先用localParam处理一下,通过返回字符串来避免jQuery 的param 方法对数据处理。

补充一下serialize方法处理,jQuery 代码:
  1. serialize: function() {
  2.     return jQuery.param( this.serializeArray() );
  3. },
复制代码
可以看出其实还是param对serializeArray来序列化,
  1. $(selector).serialize();
复制代码
所以在使用serialize的时候可以改为:
  1. $.localParam($(selector).serializeArray());
复制代码
写着写着就写完了……
1

查看全部评分

幻想乡中享幸福

UID
1004992
帖子
156603
PB币
213424
贡献
3
技术
142
活跃
2656

荣誉会员 特殊贡献勋章 水神勋章

发表于 2014-1-19 14:44:22 IP属地未知 |显示全部楼层
提交后我就感觉发错地方了。

若非心里有人.怎会暗里有光.

UID
1881189
帖子
7315
PB币
24502
贡献
0
技术
38
活跃
395

荣誉会员 8周年庆典勋章

发表于 2014-1-19 15:58:01 IP属地浙江 |显示全部楼层
AA这么叼确定还有时间看片吗?

幻想乡中享幸福

UID
1004992
帖子
156603
PB币
213424
贡献
3
技术
142
活跃
2656

荣誉会员 特殊贡献勋章 水神勋章

发表于 2014-1-19 17:08:18 IP属地未知 |显示全部楼层
鸡爪班长 发表于 2014-1-19 15:58
AA这么叼确定还有时间看片吗?

看片的时候看着看着就有想法了

Rank: 17Rank: 17Rank: 17Rank: 17Rank: 17

UID
259359
帖子
30285
PB币
38211
贡献
0
技术
63
活跃
2976

7周年庆典勋章 8周年庆典勋章 水神勋章

发表于 2014-1-19 17:31:24 IP属地江西 来自手机 |显示全部楼层
太专业?……支持

远景大水比们のLeader

Rank: 7Rank: 7Rank: 7

UID
4026306
帖子
2708
PB币
3419
贡献
0
技术
9
活跃
497

活动参与先锋 8周年庆典勋章

发表于 2014-1-19 17:42:55 IP属地广东 |显示全部楼层
水军路过,表示头大

节操役

Rank: 17Rank: 17Rank: 17Rank: 17Rank: 17

UID
1333998
帖子
17657
PB币
9464
贡献
0
技术
19
活跃
931
发表于 2014-1-19 18:12:12 IP属地上海 |显示全部楼层

那你觉得发在哪里不算发错

幻想乡中享幸福

UID
1004992
帖子
156603
PB币
213424
贡献
3
技术
142
活跃
2656

荣誉会员 特殊贡献勋章 水神勋章

发表于 2014-1-19 18:28:12 IP属地未知 |显示全部楼层
阿伯才的风格 发表于 2014-1-19 18:12
那你觉得发在哪里不算发错

丢Gist上了

节操役

Rank: 17Rank: 17Rank: 17Rank: 17Rank: 17

UID
1333998
帖子
17657
PB币
9464
贡献
0
技术
19
活跃
931
发表于 2014-1-19 18:51:56 IP属地上海 |显示全部楼层
aa65535 发表于 2014-1-19 18:28
丢Gist上了


纳尼口类?

幼儿园未毕业

Rank: 15Rank: 15Rank: 15

UID
2675209
帖子
14391
PB币
33494
贡献
0
技术
5790
活跃
2463

应用界 8周年庆典勋章

发表于 2014-1-19 20:28:52 IP属地江苏 |显示全部楼层
看不懂。路过

UID
768908
帖子
16572
PB币
14165
贡献
1
技术
30
活跃
865
发表于 2014-1-20 00:31:06 IP属地上海 |显示全部楼层
这不就是百度的做法以前有段时间百度故意设搜索参数Ie=Gbk然后所有从谷歌搜索(谷歌默认Utf-8)到的指向百度搜索结果的网址全部变乱码

Rank: 11Rank: 11Rank: 11

UID
2591535
帖子
4632
PB币
1078
贡献
0
技术
9
活跃
227

7周年庆典勋章 8周年庆典勋章

发表于 2014-1-20 01:08:16 IP属地湖南 |显示全部楼层
aa 的头像,又换了!

幻想乡中享幸福

UID
1004992
帖子
156603
PB币
213424
贡献
3
技术
142
活跃
2656

荣誉会员 特殊贡献勋章 水神勋章

发表于 2014-1-20 01:51:00 IP属地未知 |显示全部楼层
asfrim 发表于 2014-1-20 00:31
这不就是百度的做法以前有段时间百度故意设搜索参数Ie=Gbk然后所有从谷歌搜索(谷歌默认Utf-8)到的指向百度 ...

完全不一样吧,搜索使用的是get

再说那个其实是百度从gbk到utf-8的过渡阶段吧

Rank: 11Rank: 11Rank: 11

UID
1266756
帖子
3871
PB币
2974
贡献
0
技术
2
活跃
1518
发表于 2014-1-20 02:01:40 IP属地广西 |显示全部楼层
现在是AA的看片时间

幻想乡中享幸福

UID
1004992
帖子
156603
PB币
213424
贡献
3
技术
142
活跃
2656

荣誉会员 特殊贡献勋章 水神勋章

发表于 2014-1-20 03:04:15 IP属地未知 |显示全部楼层
rwzsycwan 发表于 2014-1-20 02:01
现在是AA的看片时间

已经看完了,该睡觉了
头像被屏蔽

UID
1584305
帖子
35
PB币
194
贡献
0
技术
0
活跃
6
发表于 2014-1-20 11:07:50 IP属地河北 |显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

UID
768908
帖子
16572
PB币
14165
贡献
1
技术
30
活跃
865
发表于 2014-1-20 15:45:54 IP属地上海 |显示全部楼层
aa65535 发表于 2014-1-20 01:51
完全不一样吧,搜索使用的是get

再说那个其实是百度从gbk到utf-8的过渡阶段吧

只是说编码问题方法不在考虑范围内

本来百度就是搜索关键词用Utf-8编码,只是后来又一段时间突然改Gbk大概发现好多从谷歌进来的请求怒了现在又改回去了
回顶部
Copyright (C) 2005-2024 pcbeta.com, All rights reserved
Powered by Discuz!  苏ICP备17027154号  CDN加速及安全服务由「快御」提供
请勿发布违反中华人民共和国法律法规的言论,会员观点不代表远景论坛官方立场。
远景在线 | 远景论坛 | 苹果论坛 | Win11论坛 | Win10论坛 | Win8论坛 | Win7论坛 | WP论坛 | Office论坛