一、事件回放 

今天工作时碰到了一个奇怪的问题,这个问题很早很早以前也碰到过,不过没想到过这么久了竟然又栽在这里。

当时正在联调一个项目,由于后端没有提供数据接口,于是我直接本地建立了一个 json 文件,然后把配置的URL指向这个json文件,文件内容大概如下 :

// account.json
{
success: true,
data: [{
id: "1",
name: "张XX",
job: "员工",
type: 1
}]
}

嗯,一个十分标准的Javascript对象。

然后,我的ajax代码大概如下:

function getRemoteData(url, param, success) {
$.ajax({
type: 'get',
url: url,
data: param,
dataType: 'json',
cache: false,
success: function(result) {
success(result);
},
error: function() {
alert('网络错误,请重试');
}
});
}

然后,悲剧就开始了。

这段代码,一直走入error的回调

什么原因?我开始漫漫的排查之路。

一开始,我想是不是ajax代码写错了,仔细看了看,貌似没有什么问题。
然后,由于是我使用本地json文件导致的问题,所以一直觉得是本地文件这一块出的问题。
突然想到了貌似浏览器有个对于本地文件访问的安全限制,比如chrome就有这个限制,需要在启动的时候加上参数。
但是印象中这种情况控制台会有提示的,所以应该不是这种情况,
不过我还是死马当作活马医,试一试看看,给浏览器加上了启动参数
--allow-file-access-from-files

结果,确实没用。

打开浏览器的Network,排查,发现了一个奇怪现象
在preview里面看数据
我的那句 success: true 怎么会变成 undefined: true。这是什么鬼。。。于是思路转向了json文件方向。
 
然后又想,会不会是返回的数据不是json导致的?(其实这次已经接近正确答案了),
但是我看了看文件,并没有发现什么问题,
所以猜然道是浏览器把我的json文件当作文本文件,而我dataType写了json导致解析错误?(哭!!!感觉当时应该是脑抽了)
 
然后修改ajax代码
function getRemoteData(url, param, success) {
$.ajax({
type: 'get',
url: url,
data: param,
dataType: 'text', // 改成了text
cache: false,
success: function(result) {
success(eval('(' + result + ')')); // 使用eval解析了一下
},
error: function() {
alert('网络错误,请重试');
}
});
}
果然,运行成功了。
但是,这还是治标不治本啊,而且也不能 每次 切换接口的时候改代码吧。
然后,深吸一口气,决定好好静下来想想这个问题。
 
首先看了看自己以前的代码,发现也是这么写的,完全没问题。。
不信邪,,看了看同事的代码,写法不一样,但是大体上也是这样的,也没问题。
那到底是什么问题,崩溃啊!
 
一怒之下,打开stackoverflow,开始搜索
由于方向错误,一直搜索 ajax、local file、always error等等。。
我只能说当时我的内心是崩溃的,虽然在搜索的过程中,学到了好多别的知识(各种问题链接看来看去,最后竟然看到关于react的东西去了,时间就是这样流逝掉的。。。),但关键是我这个问题还是没有解决。 
 
根据经验,往往最无厘头的问题原因往往是最简单的,心想这一定是一个很小的错误照成的,但是错误在哪里呢?
终于,功夫不负有心人,我找到了,因为那个json文件格式错了。。
在jQuery的api网站上看到了这么一句话
在 jQuery 1.4 中,JSON 格式的数据以严格的方式解析,如果格式有错误,jQuery都会被拒绝并抛出一个解析错误的异常。(见json.org的更多信息,正确的JSON格式。)
于是乎,我改了下文件 
// account.json
{
"success": true,
"date": [{
"id": "1",
"name": "张XX",
"job": "员工",
"type": 1
}]
}
好吧,运行成功了。
不知道各位看到了文件的区别吗。标准的JSON,所有的key,是需要引号的。
就是这么一个小小的问题!
 
 
二、标准JSON格式 
虽然问题解决了,但是这次的经历让我有点劫后余生的感觉,做了这么多年的前端,尽然连一个JSON都掌握不了?实在说不过去。
于是进入了JSON官网(http://json.org/json-zh.html),把那一屏半的内容好好的看了看。
都说细节是魔鬼,以前一直潜意识的就把Javascript对象当作JSON的我,这次真的好好补习了下JSON的知识。
有几个点可以和大家分享下
 
1、对象的key一定要用双引号。
     这个就是我今天碰到的问题,就不多说了。
 
2、对象的value可以有以下几种值。
    
大体上和Javascript对象没区别。
但是这里要注意的一点是,没有undefined。
也就是说
{
"success": undefined
}

这么一个JSON,是错误的。

3、对于number类型,表示的方法如下 

用科学计数法的时候会牵涉到。

三、一点感想 

回头看这个bug,真的是非常非常基础。本来解决完也就没事了,但这次却让我陷入了沉思。
记得以前有人调侃过,是说前端分太细了,CSS和Javascript都分开,以后是不是要分一个JSON工程师啊。
虽然只是一句调侃,但是我想大部分前端对于JSON都抱着一种“哦,就是一个Javascript对象”这种态度,而没有去认真去看一看它的定义。
 
回想最近两年学习与接触的前端知识,各种工程化工具,各种MV*框架,前端应用架构模式等。而那些基础的东西确实很久没有关注了。
其实之前我一直觉得自己基础还挺好的,从11年入行以来,泡着蓝色理想论坛 ,HTML,CSS一步一步走过来,也算踏实。
 
又想起前不久阿当舌战群儒,争论关于前端基础和层出不穷的新技术问题。虽然不能说完全认可他的观点,但是现在也挺能理解。
是时候好好静下来,重拾那些前端最根本的东西了。

转载本站文章请注明作者和出处 哎呦大黄 – http://www.cnblogs.com/season-huang/,请勿用于任何商业用途

一个粗心的Bug,JSON格式不规范导致AJAX错误的更多相关文章

  1. 修复一个mysqlbinlog_flashback不支持json格式问题

    修复一个mysqlbinlog_flashback不支持json格式问题 , 有问题可以反馈留言 , 如下盘: 最简单的例子为 python mysqlbinlog_back.py --host=&q ...

  2. 模拟一个http 请求的json格式报文,带 rsa 签名操作

    一.对需要加密的字符串,定义RsaSignUnsign 类,代码如下: 实现了: 1.实现了生成新的pubkey.pri_key方法: 2.将新生成的keys 写入文件: 3.从文件获取pubkey. ...

  3. C#开发的WebService使用JSON格式传递数据+Ajax测试

    [C#]  WebService 使用 JSON 格式傳遞筆記 + JQuery 測試 0 2 因為一些因素,必須改寫WebService,很傳統,但是很多公司還在用.. 因為XML 的關係,不想讓他 ...

  4. JS实现的一个query字符串转Json格式数据的方法

    输入字符串的格式是 a=1&b=2&c=3 $.par2Json = function (string, overwrite) { var obj = {}, pairs = stri ...

  5. JavaWeb返回Json格式数据JQuery Ajax无法解析的问题

    今天在写实验室的傻逼Java Web小项目的时候,有一个需要发布内容的地方,因为想做的让用户感觉优雅一点 所以就是用了Ajax来做,本来很简单的一个小玩意,竟然花了半个多小时的时间,主要是将时间花在了 ...

  6. JSON缺包导致的错误

    Json-lib 需要的 jar 包 commons-beanutils-1.8.3.jar commons-collections-3.2.1.jar commons-lang-2.6.jar co ...

  7. jQuery里$.post请求,后台返回结果为“json”格式,前台解析错误问题记录

    在JSP页面使用$.post请求后台返回json数据时,在最后 必须加上返回数据格式为json的才行.不然JSP页面解析会出错.

  8. 如何解决jersey框架中以json格式返回数组,当数组中元素一个时json格式不对

    原文地址:http://www.cnblogs.com/swpk/p/3566536.html?utm_source=tuicool jersey 是oracle 出的一个较好的REST框架.使用此框 ...

  9. WP8解析JSON格式(使用Newtonsoft.Json包)

    DOTA2 WebAPI请求返回的格式有两种,一种是XML,一种是JSON,默认是返回JSON格式. 这里举一个简单的解析JSON格式的例子(更多JSON操作): { "response&q ...

随机推荐

  1. 几个有趣的WEB设备API(二)

    浏览器和设备之间还有很多有趣的接口, 1.屏幕朝向接口 浏览器有两种方法来监听屏幕朝向,看是横屏还是竖屏. (1)使用css媒体查询的方法 /* 竖屏 */ @media screen and (or ...

  2. react-redux

    1. 首先redux,与react是两个独立的个体,项目中可以只用react,也可以只用redux 1.1 react-redux: 是一个redux作者专门为react制作的 redux, 增加了新 ...

  3. Ubuntu 16.10 安装byzanz截取动态效果图工具

    1.了解byzanz截取动态效果图工具 byzanz能制作文件小,清晰的GIF动态效果图,不足就是,目前只能通过输入命令方式来录制. byzanz主要的参数选项有: -d, --duration=SE ...

  4. javascript数组查重方法总结

    文章参考地址:http://blog.csdn.net/chengxuyuan20100425/article/details/8497277 题目 对下列数组去重: var arr = ['aa', ...

  5. 在开启DRS的集群中修复VMware虚拟主机启动问题

    通过iSCSI方式连接到ESXi主机上的外挂存储意外失联了一段时间,导致部分虚拟主机在集群中呈现出孤立的状态,单独登陆到每台ESXi上可以看到这些虚拟主机都变成了unknow状态.因为有过上一次(VM ...

  6. [转]Patch文件结构详解

    N久不来 于是不知道扔在哪儿于是放这里先 如果你觉得碍事的话 帮我扔到合适的版块去.. 导读这是一篇说明文 它介绍了标准冒险岛更新文件(*.patch;*.exe)的格式文章的最后附了一段C#的参考代 ...

  7. IdentityServer4 使用OpenID Connect添加用户身份验证

    使用IdentityServer4 实现OpenID Connect服务端,添加用户身份验证.客户端调用,实现授权. IdentityServer4 目前已更新至1.0 版,在之前的文章中有所介绍.I ...

  8. .NET面试题集锦①(Part一)

    一.前言部分 文中的问题及答案多收集整理自网络,不保证100%准确,还望斟酌采纳. 1.面向对象的思想主要包括什么? 答:任何事物都可以理解为对象,其主要特征: 继承.封装.多态.特点:代码好维护,安 ...

  9. 【夯实Mysql基础】MySQL性能优化的21个最佳实践 和 mysql使用索引

    本文地址 分享提纲: 1.为查询缓存优化你的查询 2. EXPLAIN 你的 SELECT 查询 3. 当只要一行数据时使用 LIMIT 1 4. 为搜索字段建索引 5. 在Join表的时候使用相当类 ...

  10. 【centos7常用技巧】RPM打包

    一.RPM打包的目的 1.当目标机中不存在编译环境时,可以先在本地环境中编译打包,然后直接在目标机中用rpm -ivh *.rpm安装即可. 2.当需要在目标机中安装多个软件或者增加多个文件时,可以将 ...