一、事件回放
今天工作時碰到了一個奇怪的問題,這個問題很早很早以前也碰到過,不過沒想到過這么久了竟然又栽在這里。
當時正在聯調一個項目,由於后端沒有提供數據接口,於是我直接本地建立了一個 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/ ,請勿用於任何商業用途