在前端頁面展現數據的時候,一般都須要處理來自後端的json數據。一般這個過程都是很是簡單的,好比經過jQuery的ajax。可是若是服務器傳來的json中包含一個很大的整數,如 { "id": 296675198462066688 } ,那麼接受後會發現變成了 { id: 296675198462066700 } 。javascript
簡單的解決方法,讓後端傳給你string類型
可是後端的人會說:大家前端怎麼顯示個long類型都搞不定!
複製代碼
js是弱類型語言,全部的數字類型統稱爲Number類型,不區分int、long、double等。而Number是根據IEEE 754標準中的double來實現的,即全部的Number類型都是64位雙精度實型。segmentfault上提供了一個對 IEEE 574標準 很是友好的講解,這裏再也不講述。html
js內置有32位整數,而number類型的安全整數是53位。若是超過53位的,你不能用json傳遞,須要用其餘數據類型,好比字符串,或拆分紅兩個數據字段。前端
GitHub開源項目—— Jison,號稱「bison in javascript」,經過它能夠實現對後端返回數據的從新定義一個本身的json parser。java
在拿到接口請求返回的數據的時候,不用json自帶的那個parse方法,而是經過本身定義了一個json轉換方法,而後再response給前端,這樣一來前端拿到的數據就是一個處理過的json數據。ios
首先使用Node安裝Jisongit
npm install jison -g
複製代碼
同時在 lib 目錄下提供了 cli.js 來生成咱們想自定義的parser。參數有兩個(詳見cli.js代碼), cli.js grammaFile lexFile ,grammaFile是語法文件,lexFile是詞表文件。github
下面就是怎麼寫這兩個文件了,能夠經過 文檔 來學習一下這類文件的語法。若是不想這麼麻煩,還能夠在jison做者的另外一個項目—— jsonlint 裏面找到,在github中該項目的src目錄下提供了jsonlint.y(grammaFile)和jsonlint.l(lexFile)兩個文件。使用這兩個文件能夠直接生成jsonlint.js,放到網頁中當json parser來使用。ajax
這裏咱們以修改jsonlint裏面的兩個文件爲例生成咱們所須要的json parsenpm
咱們的目的是讓一些會丟失精度的整數被保留下來,最好的方法是:當整數超過了安全範圍的時候,使用字符串表示。咱們能夠經過修改jsonlint.y來達到這個目的。json
本來對JSONNumber的定義是
JSONNumber
: NUMBER
{$$ = Number(yytext);}
;
複製代碼
在這裏yytext是要進行解析的原始數據,$$是結果。咱們能夠修改爲
JSONNumber
: NUMBER
{$$ = yytext == String(Number(yytext))? Number(yytext): yytext;}
;
複製代碼
==> 生成咱們要的 jsonlint.js:
git clone git://github.com/zaach/jsonlint.git
cd src
jison jsonlint.y jsonlint.l
複製代碼
這裏以Vue項目爲例:
一、將自定義的 jsonlint.js 放到 static 目錄下
二、在 index.html 中引入
<script src="./static/jsonlint/jsonlint.js"></script>
複製代碼
三、在咱們請求的返回數據中,作一層攔截轉換
此處以 axios 的實現方法爲例:
// transformResponse 選項容許咱們在數據傳送到 `then/catch` 方法以前對數據進行改動
axios.defaults.transformResponse = [
function(data) {
return jsonlint.parse(data)
}
]
複製代碼
綜上,經過自定義JSON轉化避免long類型數據溢出,能夠實現long類型數據在前端正常顯示。
注意: 這個方法的確能夠實現前端拿到的數據不出現精度丟失問題,可是再瀏覽器中的Preview上查看數據仍是一個丟失的錯誤數據,這個是由於瀏覽器它用的仍是本身原始的那個json parse方法。
後記: 小夥伴們,若是有錯誤或者不嚴謹的地方,請務必給予指正,十分感謝。若是以爲本文還不錯,記得點個贊哦! 本文首發地址爲: Vae's Blog