經常我們會遇到後端返回的資料JSON的格式不正常,會出現key沒有引號的情況,如:

var str = ‘{a: 1, b: 2}’;

當然,這種情況可以讓後端修改返回資料格式,但是往往再面試或則其他時候有可能會問道:如何去解析這種型別的字串?

畢竟標題是“奇技淫巧”,那常規的eval和new Function這裡就不多說。

方式一:[native code]。constructor

使用JS內建物件的任意原型方法,如:Object。prototype。toString,Array。prototype。push,RegExp。prototype。test等等,其實這裡的實質原理還是new Function。

Object。prototype。toString。constructor === Function // true

Array。prototype。push。constructor === Function // true

RegExp。prototype。test。constructor === Function // true

var json = ‘{a: 1, b: 2}’;

json = ‘window。result = ’ + json; // 嚴格模式下eval有自己的作用於,直接var接受JSON是獲取不到值的,需要掛載再window全域性下面

Object。prototype。toString。constructor(json)(); // 1

console。log(result); // {a: 1, b: 2}

方式二:script標籤 + innerHTML

直接插入script標籤,同時把字串拼接一個接受的變數innerHTML進去。

var json = ‘{a: 1, b: 2}’;

var script = document。createElement(‘script’);

script。innerHTML = ‘var result = ’ + json;

document。body。appendChild(script);

console。log(result); // {a: 1, b: 2}

方式三:script標籤 + src

字串透過blob可以轉二進位制,再透過window。URL。createObjectURL轉url。

var json = ‘{a: 1, b: 2}’;

var blob = new Blob([‘var result = ’ + json]);

var src = window。URL。createObjectURL(blob);

var script = document。createElement(‘script’);

script。src = src;

document。body。appendChild(script);

script。onload = function(){

console。log(result); // {a: 1, b: 2}

}

PS:由於是src載入的,需要再onload才能獲取到資料,同時有blob轉的url,需要在有伺服器的條件下才能測試,

直接開啟一個本地html檔案無法測試,需要測試的可以直接開啟一個百度什麼的網站,F12在控制檯測試。

方式四:Worker

同上一條一樣建立url,然後透過Worker執行,但是這裡接受資料就只能透過postMessage和onmessage:

var json = ‘{a: 1, b: 2}’;

var blob = new Blob([‘postMessage(’ + json + ‘)’]);

var src = window。URL。createObjectURL(blob);

var worker = new Worker(src);

worker。onmessage = function(e){

console。log(e。data); // {a: 1, b: 2}

}

PS:同上,需要再伺服器的條件下測試。

方式五:location。href

經常我們再寫點選事件的時候會這樣寫:

同時隨便開啟一個頁面,再位址列輸入:javascript:alert(1),可以看到,程式碼執行了,並且頁面並沒有跳轉變化,SO,我們可以利用這一點。

PS:複製到位址列預設會去掉javascript:,需要手動補上。

var json = ‘{a: 1, b: 2}’;

location。href = ‘javascript:var result = ’ + json;

setTimeout(function(){

console。log(result); // {a: 1, b: 2}

}, 0);