Bezpieczne przekształcanie łańcucha JSON w obiekt

Biorąc pod uwagę ciąg danych JSON, Jak mogę bezpiecznie przekształcić ten ciąg w obiekt JavaScript?

Oczywiście mogę to zrobić z czymś takim:

var obj = eval("(" + json + ')');

Ale to pozostawia mnie podatnym na łańcuch JSON zawierający inny kod, który wydaje się bardzo niebezpieczny po prostu eval.

Author: Kamil Kiełczewski, 2008-09-05

28 answers

JSON.parse(jsonString) to czyste podejście JavaScript, o ile możesz zagwarantować rozsądnie nowoczesną przeglądarkę.

 2017
Author: Jonathan.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-26 18:41:03

Metoda jQuery jest obecnie przestarzała. Użyj tej metody zamiast:

let jsonObject = JSON.parse(jsonString);

oryginalna odpowiedź przy użyciu przestarzałej funkcjonalności jQuery :

Jeśli używasz jQuery po prostu użyj:

jQuery.parseJSON( jsonString );

To dokładnie to, czego szukasz (zobacz dokumentację jQuery ).

 884
Author: Alex V,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-24 15:50:32

Ta odpowiedź jest dla IE

Ta odpowiedź jest nieaktualna i odpowiedź Jonathana powyżej (JSON.parse(jsonString)) jest teraz najlepszą odpowiedzią .

JSON.org posiada parsery JSON dla wielu języków, w tym cztery różne dla JavaScript. Wierzę, że większość ludzi rozważy json2.JS ich implementacja goto.

 162
Author: John,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-27 00:58:19

Użyj prostego przykładu kodu w " JSON.parse()":

var jsontext = '{"firstname":"Jesper","surname":"Aaberg","phone":["555-0100","555-0120"]}';
var contact = JSON.parse(jsontext);

I odwrotnie:

var str = JSON.stringify(arr);
 75
Author: Ronald Coarite,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-27 00:59:25

Nie jestem pewien innych sposobów, aby to zrobić, ale oto jak to zrobić w Prototype (JSON tutorial) .

new Ajax.Request('/some_url', {
  method:'get',
  requestHeaders: {Accept: 'application/json'},
  onSuccess: function(transport){
    var json = transport.responseText.evalJSON(true);
  }
});

Wywołanie evalJSON() z true, ponieważ argument dezynfekuje przychodzący łańcuch.

 24
Author: Mark Biek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-27 00:59:49

To wydaje się być problemem:

Wejście, które jest odbierane przez Ajax websocket etc, i będzie w formacie String, ale musisz wiedzieć, czy jest JSON.parsable. Touble jest, jeśli zawsze uruchamiasz go przez JSON.parse, program może kontynuować "pomyślnie", ale nadal zobaczysz błąd wyrzucony w konsoli z przerażającym "Error: unexpected token 'x'".

var data;

try {
  data = JSON.parse(jqxhr.responseText);
} catch (_error) {}

data || (data = {
  message: 'Server error, please retry'
});
 24
Author: Cody,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-27 01:02:00

Jeśli używasz jQuery , Możesz również użyć:

$.getJSON(url, function(data) { });

Wtedy możesz robić takie rzeczy jak

data.key1.something
data.key1.something_else

Itd.

 20
Author: Leanan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-27 01:02:57
$.ajax({
  url: url,
  dataType: 'json',
  data: data,
  success: callback
});

Wywołanie zwrotne przekazuje zwrócone dane, które będą obiektem JavaScript lub tablicą zdefiniowaną przez strukturę JSON i przetwarzane przy użyciu metody $.parseJSON().

 16
Author: Prahlad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-16 23:38:26

Dla Zabawy, oto sposób użycia funkcji:

 jsonObject = (new Function('return ' + jsonFormatData))()
 14
Author: lessisawesome,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-27 01:03:26

Używanie {[1] } jest prawdopodobnie najlepszym sposobem.

Oto przykład live demo .

var jsonRes = '{ "students" : [' +
          '{ "firstName":"Michel" , "lastName":"John" ,"age":18},' +
          '{ "firstName":"Richard" , "lastName":"Joe","age":20 },' +
          '{ "firstName":"James" , "lastName":"Henry","age":15 } ]}';
var studentObject = JSON.parse(jsonRes);
 11
Author: Bharath Kumaar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-27 01:04:23

Najprostszy sposób użycia metody parse():

var response = '{"result":true,"count":1}';
var JsonObject= JSON.parse(response);

Następnie można uzyskać wartości elementów JSON, na przykład:

var myResponseResult = JsonObject.result;
var myResponseCount = JsonObject.count;

Używając jQuery zgodnie z opisem w jQuery.parseJSON() dokumentacja:

JSON.parse(jsonString);
 9
Author: Jorgesys,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-27 01:05:43

Spróbuj użyć metody z tym obiektem danych. ex:Data='{result:true,count:1}'

try {
  eval('var obj=' + Data);
  console.log(obj.count);
}
catch(e) {
  console.log(e.message);
}

Ta metoda naprawdę pomaga w Nodejs gdy pracujesz z programowaniem portów szeregowych

 9
Author: GPrathap,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-03-17 12:44:43

Znalazłem "lepszy" sposób:

W CoffeeScript:

try data = JSON.parse(jqxhr.responseText)
data ||= { message: 'Server error, please retry' }

W Javascript:

var data;

try {
  data = JSON.parse(jqxhr.responseText);
} catch (_error) {}

data || (data = {
  message: 'Server error, please retry'
});
 5
Author: Dorian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-18 13:38:07

Parsowanie JSON jest zawsze bolesne. Jeśli Dane wejściowe nie są zgodne z oczekiwaniami, powoduje to błąd i powoduje awarię tego, co robisz.

Możesz użyć poniższej funkcji tiny, aby bezpiecznie przetworzyć dane wejściowe. Zawsze obraca obiekt, nawet jeśli wejście nie jest poprawne lub jest już obiektem, co jest lepsze w większości przypadków:

JSON.safeParse = function (input, def) {
  // Convert null to empty object
  if (!input) {
    return def || {};
  } else if (Object.prototype.toString.call(input) === '[object Object]') {
    return input;
  }
  try {
    return JSON.parse(input);
  } catch (e) {
    return def || {};
  }
};
 4
Author: Tahsin Turkoz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-27 01:07:35
JSON.parse(jsonString);

Json.parse zmieni się w obiekt.

 3
Author: Shekhar Tyagi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-19 13:05:06

Jeśli mamy taki ciąg znaków:

"{\"status\":1,\"token\":\"65b4352b2dfc4957a09add0ce5714059\"}"

Wtedy możemy po prostu użyć JSON.parse dwa razy, aby przekonwertować ten łańcuch na obiekt JSON:

var sampleString = "{\"status\":1,\"token\":\"65b4352b2dfc4957a09add0ce5714059\"}"
var jsonString= JSON.parse(sampleString)
var jsonObject= JSON.parse(jsonString)

I możemy wyodrębnić wartości z obiektu JSON używając:

// instead of last JSON.parse:
var { status, token } = JSON.parse(jsonString);

Wynik będzie:

status = 1 and token = 65b4352b2dfc4957a09add0ce5714059
 3
Author: Hamid Araghi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-27 01:08:42

JSON.parse() konwertuje dowolny łańcuch JSON przekazany do funkcji do obiektu JSON.

Aby lepiej to zrozumieć, naciśnij F12 , aby otworzyć "Inspect Element" w przeglądarce i przejdź do konsoli, aby napisać następujące polecenia:

var response = '{"result":true,"count":1}'; //sample json object(string form)
JSON.parse(response); //converts passed string to JSON Object.

Teraz uruchom polecenie:

console.log(JSON.parse(response));

Zostanie wyświetlony jako obiekt {result: true, count: 1}.

Aby użyć tego obiektu, możesz przypisać go do zmiennej, może obj:

var obj = JSON.parse(response);

Używając obj i operatora dot (.) możesz właściwości dostępu obiektu JSON.

Spróbuj uruchomić polecenie:

console.log(obj.result);
 3
Author: Pushkar Kathuria,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-27 01:11:59

Oficjalna dokumentacja :

Metoda JSON.parse() przetwarza łańcuch JSON, konstruując wartość JavaScript lub obiekt opisany łańcuchem. Opcjonalna funkcja reviver może być dostarczona do wykonania transformacji na wynikowym obiekcie przed jego zwróceniem.

Składnia:

JSON.parse(text[, reviver])

Parametry:

text : Łańcuch do przetworzenia jako JSON. Opis składni JSON znajduje się w obiekcie JSON.

reviver (optional) : If a function, this prescribes w jaki sposób wartość pierwotnie wytworzona przez parsowanie jest przekształcana, zanim zostanie zwrócona.

Return value

Obiekt odpowiadający podanemu tekstowi JSON.

Wyjątki

Rzuca wyjątek SyntaxError, jeśli łańcuch do analizy nie jest poprawny JSON.

 3
Author: Salomon Zhang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-27 01:15:09

Konwersja obiektu do JSON, a następnie parsowanie go, działa dla mnie, jak:

JSON.parse(JSON.stringify(object))
 2
Author: Liuver Reynier Durán Pérez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-28 18:16:34

Przeanalizuj łańcuch JSON za pomocą JSON.parse(), a dane staną się obiektem JavaScript:

JSON.parse(jsonString)

Tutaj JSON reprezentuje przetwarzanie zbioru danych JSON.

Wyobraź sobie, że otrzymaliśmy ten tekst z serwera www:

'{ "name":"John", "age":30, "city":"New York"}'

Aby przetworzyć obiekt JSON:

var obj = JSON.parse('{ "name":"John", "age":30, "city":"New York"}'); 

Tutaj {[6] } znajduje się odpowiedni obiekt JSON, który wygląda następująco:

{ "name":"John", "age":30, "city":"New York"}

Aby pobrać wartość użyj operatora .:

obj.name // John
obj.age //30

Konwertuj obiekt JavaScript na ciąg znaków za pomocą JSON.stringify().

 2
Author: Amitesh Bharti,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-27 01:17:58

Tylko do cover parse dla różnych typów Wejściowych

Analizuj dane za pomocą JSON.parse (), a dane staną się obiektem JavaScript.

var obj = JSON.parse('{ "name":"John", "age":30, "city":"New York"}');

Podczas korzystania z JSON.parse () na JSON pochodzącym z tablicy metoda zwróci tablicę JavaScript zamiast obiektu JavaScript.

var myArr = JSON.parse(this.responseText);
console.log(myArr[0]);

Obiekty Date nie są dozwolone w JSON. Dla dat zrobić coś takiego

var text = '{ "name":"John", "birth":"1986-12-14", "city":"New York"}';
var obj = JSON.parse(text);
obj.birth = new Date(obj.birth);

Funkcje nie są dozwolone w JSON. Jeśli chcesz dołączyć funkcję, napisz ją jako sznurek.

var text = '{ "name":"John", "age":"function () {return 30;}", "city":"New York"}';
var obj = JSON.parse(text);
obj.age = eval("(" + obj.age + ")");
 1
Author: MOnkey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-02-23 05:34:13

Starsze pytanie, wiem, jednak nikt nie zauważy tego rozwiązania za pomocą new Function(), anonimowej funkcji, która zwraca dane.


Tylko przykład:

 var oData = 'test1:"This is my object",test2:"This is my object"';

 if( typeof oData !== 'object' )
  try {
   oData = (new Function('return {'+oData+'};'))();
  }
  catch(e) { oData=false; }

 if( typeof oData !== 'object' )
  { alert( 'Error in code' ); }
 else {
        alert( oData.test1 );
        alert( oData.test2 );
      }

Jest to trochę bardziej bezpieczne, ponieważ wykonuje ono wewnątrz funkcji i nie kompiluje się bezpośrednio w kodzie. Jeśli więc wewnątrz znajduje się deklaracja funkcji, nie będzie ona powiązana z domyślnym obiektem window.

Używam tego do 'kompilowania' ustawień konfiguracyjnych elementów DOM (na przykład danych atrybut) prosty i szybki.

 0
Author: Codebeat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-19 01:32:24

Podsumowanie:

Javascript (zarówno przeglądarka jak i NodeJS) mają wbudowany obiekt JSON. Na tym obiekcie znajdują się 2 wygodne metody obsługi JSON. Są następujące:

  1. JSON.parse() przyjmuje JSON jako argument, zwraca obiekt JS
  2. JSON.stringify() przyjmuje obiekt JS jako argument zwraca JSON obiekt

Inne zastosowania:

Poza tym za bardzo wygodne radzenie sobie z JSON mogą być używane do innych środków. Kombinacja obu JSON metody pozwalają nam bardzo łatwo tworzyć głębokie klony tablic lub obiektów. Na przykład:

let arr1 = [1, 2, [3 ,4]];
let newArr = arr1.slice();

arr1[2][0] = 'changed'; 
console.log(newArr); // not a deep clone

let arr2 = [1, 2, [3 ,4]];
let newArrDeepclone = JSON.parse(JSON.stringify(arr2));

arr2[2][0] = 'changed'; 
console.log(newArrDeepclone); // A deep clone, values unchanged
 0
Author: Willem van der Veen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-18 10:00:42

Możesz również użyć funkcji reviver do filtrowania.

var data = JSON.parse(jsonString, function reviver(key, value) {
   //your code here to filter
});

Aby uzyskać więcej informacji przeczytaj JSON.parse.

 0
Author: Durgpal Singh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-27 01:15:42

JSON.parse jest właściwym sposobem konwersji ciągu znaków na obiekt, ale jeśli łańcuch, który jest analizowany, nie jest obiektem lub jeśli łańcuch nie jest poprawny, spowoduje to błąd, który spowoduje złamanie reszty kodu, więc idealnie jest owinąć JSON.funkcja parse wewnątrz try-catch like

try{
   let obj = JSON.parse(string);
}catch(err){
   console.log(err);
}
 0
Author: deepak thomas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-15 07:43:11

Wydajność

Jest już dobra odpowiedź na to pytanie, ale byłem ciekaw wydajności i dzisiaj 2020.09.21 przeprowadzam testy na MacOs HighSierra 10.13.6 na Chrome v85, Safari v13. 1. 2 i Firefox v80 dla wybranych rozwiązań.

Wyniki

  • Na Chrome 'IE podejście jest szybkie (ale dla obiektów o dużej głębokości N=1000 są one crash:" maximum stack call exceed)
  • eval (A) jest szybki / Średnio szybki we wszystkich przeglądarkach
  • JSON.parse (D,E) są najszybsze na Safari i Firefox

Tutaj wpisz opis obrazka

Szczegóły

Wykonuję 4 przypadki testów:

  • dla małego, płytkiego obiektu tutaj
  • dla małego głębokiego obiektu tutaj
  • dla dużego, płytkiego obiektu tutaj
  • dla dużego, głębokiego obiektu tutaj

Obiekt użyty w powyższych testach pochodzi z tutaj

let obj_ShallowSmall = {
  field0: false,
  field1: true,
  field2: 1,
  field3: 0,
  field4: null,
  field5: [],
  field6: {},
  field7: "text7",
  field8: "text8",
}

let obj_DeepSmall = {
  level0: {
   level1: {
    level2: {
     level3: {
      level4: {
       level5: {
        level6: {
         level7: {
          level8: {
           level9: [[[[[[[[[['abc']]]]]]]]]],
  }}}}}}}}},
};

let obj_ShallowBig = Array(1000).fill(0).reduce((a,c,i) => (a['field'+i]=getField(i),a) ,{});


let obj_DeepBig = genDeepObject(1000);



// ------------------
// Show objects
// ------------------

console.log('obj_ShallowSmall:',JSON.stringify(obj_ShallowSmall));
console.log('obj_DeepSmall:',JSON.stringify(obj_DeepSmall));
console.log('obj_ShallowBig:',JSON.stringify(obj_ShallowBig));
console.log('obj_DeepBig:',JSON.stringify(obj_DeepBig));




// ------------------
// HELPERS
// ------------------

function getField(k) {
  let i=k%10;
  if(i==0) return false;
  if(i==1) return true;
  if(i==2) return k;
  if(i==3) return 0;
  if(i==4) return null;
  if(i==5) return [];
  if(i==6) return {};  
  if(i>=7) return "text"+k;
}

function genDeepObject(N) {
  // generate: {level0:{level1:{...levelN: {end:[[[...N-times...['abc']...]]] }}}...}}}
  let obj={};
  let o=obj;
  let arr = [];
  let a=arr;

  for(let i=0; i<N; i++) {
    o['level'+i]={};
    o=o['level'+i];
    let aa=[];
    a.push(aa);
    a=aa;
  }

  a[0]='abc';
  o['end']=arr;
  return obj;
}

Poniżej fragment przedstawia wybrane rozwiązania

// src: https://stackoverflow.com/q/45015/860099
function A(json) {
  return eval("(" + json + ')');
}

// https://stackoverflow.com/a/26377600/860099
function B(json) {
  return (new Function('return ('+json+')'))()
}


// improved https://stackoverflow.com/a/26377600/860099
function C(json) {
  return Function('return ('+json+')')()
}

// src: https://stackoverflow.com/a/5686237/860099
function D(json) {
  return JSON.parse(json);
}

// src: https://stackoverflow.com/a/233630/860099
function E(json) {
  return $.parseJSON(json)
}



 
// --------------------
// TEST
// --------------------

let json = '{"a":"abc","b":"123","d":[1,2,3],"e":{"a":1,"b":2,"c":3}}';

[A,B,C,D,E].map(f=> {  
  console.log(
    f.name + ' ' + JSON.stringify(f(json))
  )})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
This shippet only presents functions used in performance tests - it not perform tests itself!

A oto Przykładowe wyniki dla chrome

Tutaj wpisz opis obrazka

 0
Author: Kamil Kiełczewski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-09-21 09:11:33

Spróbuj tego.Ten jest napisany maszynopisem.

         export function safeJsonParse(str: string) {
               try {
                 return JSON.parse(str);
                   } catch (e) {
                 return str;
                 }
           }
 -1
Author: Supun Dharmarathne,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-30 06:31:48
/**
 * Safely turning a JSON string into an object
 *
 * @param {String} str - JSON String
 * @returns deserialized object, false if error
 */
export function jsonParse(str) {
  let data = null;
  try {
    data = JSON.parse(str);
  } catch (err) {
    return false;
  }
  return data;
}
 -1
Author: 山茶树和葡萄树,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-12-30 05:28:56