前言
当我通过跨域Ajax请求京东的商品库存接口时,返回的中文出现了乱码。有意思的是,当我多次请求尝试时,返回提会改变,并且返回的编码也会改变,所以偶尔会返回一个UTF-8的返回体。示例的请求接口如下:
http://c0.3.cn/stocks?callback=getStockCallback&type=getstocks&skuIds=32399605916&area=15_1213_1214_0&1572054766314
- skuIds 商品的id
- getStockCallback 回调函数;可以使用这个名字来编写一个回调处理函数
- area 地区编码;需要查询库存的地区
正常的请求如下,会乱码:
!
可是当多次请求以后,返回体会发生改变,并且中文也能显示了:
解决方法
1.全局查找中文判断
由于第一种返回体中文是乱码的,起初我第一种判定方法是查找有无“现货”和“无货”两种关键词。例如我想查询“现货”,代码如下:
1 | if (r.responseText.indexOf( '现货' ) > 0) { |
但是这种方法比较蠢。原因有下几点:
- 每次返回中不一定都是中文,即使“有货”,也不一定是中文显示
- 当“有货”时,但是不是中文,代码还一直以为无货。时间过去了以后很有可能被他人购买了,即使“有货”也真的会变成“无货”
2.使用Script的标签来完成跨域以及GBK解码
使用<script>
标签来跨域请求;因为浏览器的同源策略限制,请求非当前页码的域名的时候,会被浏览器阻止,但是<script>
标签受此影响。其实Ajax的跨域请求也是利用该原理。但是,<scprit>
标签的优点是可以设置编码格式,也就是说即使后台返回了GBK编码,我们照样能够得到中文字符串,下面是代码示例:
1 | //检查库存 |
其实光有一个请求函数还是不够的。我们还需要编写一个回调函数来处理返回值。这里啰嗦几句,很多新人对这个玩意理解不够很容易造成困扰,包括我之前也是这样。所谓回调函数个人理解是:当向服务器发送请求成功以后,我们会定义一个函数来进行处理。也就是:返回后调用函数,简称回调函数。
回调函数是定义在请求链接中,也就是上面URL参数里的:callback=getStockCallback
,那么函数名就是:getStockCallback
,我的回调函数如下:
1 | //回调函数 |
至此,该代码就能完整的解析GBK编码了
3.意外发现,不需要判断中文也能知道库存状态
其实,在我编码的过程中发现,能不能解析中文不重要,因为在返回体重已经有一个字段已经表明了库存状态了,请参考以下代码:
1 | //判断状态 |
所以如果只需要监测库存的话,判断下这个stockState
字段就可以了。
其它解决方法
我依然希望能找到Ajax 解码GBK方法,因为script标签还是有些繁琐。