简体   繁体   中英

How to parse a JSON that has nested escaped JSON inside it in javascript?

Update : This JSON is just one of the examples, I need to read these JSON files and pass them to a function that accepts JSONObject.

I have one JSON like this -

    {   "log": {
    "version": "1.2",
    "entries": [
      {
        "response": {
          "status": 200,
          "statusText": "OK",
          "httpVersion": "HTTP/1.1",
          "headers": [
            {
              "name": "Date",
              "value": "Tue, 19 Feb 2019 13:50:34 GMT"
            },
            {
              "name": "CF-RAY",
              "value": "4ab934095ceacc4c-ZRH"
            },
            {
              "name": "Content-Encoding",
              "value": "gzip"
            }
          ],
          "cookies": [],
          "content": {
            "size": 155,
            "mimeType": "application/json",
            "compression": 0,
            "text": "{\"ip\":\"45.64.195.115\",\"ip_decimal\":759219059,\"country\":\"India\",\"country_eu\":false,\"country_iso\":\"IN\",\"city\":\"nocity\",\"latitude\":98.975,\"longitude\":92.8258}"
          },
          "redirectURL": "",
          "headersSize": 230,
          "bodySize": 155,
          "_transferSize": 385
        },
        "cache": {},
        "timings": {
          "blocked": 6.805000007039867,
          "dns": -1,
          "ssl": -1,
          "connect": -1,
          "send": 0.22000000000000064,
          "wait": 174.87700000413787,
          "receive": 11.549999995622784,
          "_blocked_queueing": 0.8590000070398673
        },
        "serverIPAddress": "100.28.12.103",
        "_initiator": {
          "type": "other"
        },
        "_priority": "VeryHigh",
        "connection": "509100",
        "pageref": "page_2"
      }
    ]   
  } 
}

And I am trying to parse is using -

var parsed = JSON.parse(myJson);

this throws error at this part - "text": "{\\"ip\\":\\"49.64.194.115\\",\\"ip_decimal\\":75

because it is an escaped nested JSON.

How do I do it? I found one method here but does not apply to this problem.

You json can already be used as an javascript object

const myJSON = {
   "log":{
      "version":"1.2",
      "entries":[
         {
            "response":{
               "status":200,
               "statusText":"OK",
               "httpVersion":"HTTP/1.1",
               "headers":[
                  {
                     "name":"Date",
                     "value":"Tue, 19 Feb 2019 13:50:34 GMT"
                  },
                  {
                     "name":"CF-RAY",
                     "value":"4ab934095ceacc4c-ZRH"
                  },
                  {
                     "name":"Content-Encoding",
                     "value":"gzip"
                  }
               ],
               "cookies":[

               ],
               "content":{
                  "size":155,
                  "mimeType":"application/json",
                  "compression":0,
                  "text":"{\"ip\":\"45.64.195.115\",\"ip_decimal\":759219059,\"country\":\"India\",\"country_eu\":false,\"country_iso\":\"IN\",\"city\":\"nocity\",\"latitude\":98.975,\"longitude\":92.8258}"
               },
               "redirectURL":"",
               "headersSize":230,
               "bodySize":155,
               "_transferSize":385
            },
            "cache":{

            },
            "timings":{
               "blocked":6.805000007039867,
               "dns":-1,
               "ssl":-1,
               "connect":-1,
               "send":0.22000000000000064,
               "wait":174.87700000413787,
               "receive":11.549999995622784,
               "_blocked_queueing":0.8590000070398673
            },
            "serverIPAddress":"100.28.12.103",
            "_initiator":{
               "type":"other"
            },
            "_priority":"VeryHigh",
            "connection":"509100",
            "pageref":"page_2"
         }
      ]
   }
}

If you want to parse 'log.entries.response.content.text' you can do something like this

if (myJSON.log && myJSON.log.entries && myJSON.log.entries.length > 0) {
  for (const element of myJSON.log.entries) {
    if (element.response && element.response.content && element.response.content.text) {
      try {
        element.response.content.text = JSON.parse(element.response.content.text);
      } catch (error) {
        console.log('do nothing')
      }
    }
  }
}

it's because

myJson.log.entries[0].response.content.text

is after JSON stringify, so you need before to parse it and after that parse the entire object.
so do this:

myJson.log.entries[0].response.content.text = JSON.parse(myJson.log.entries[0].response.content.text);

Quite simple: you just need to be aware of when you have a javascript object, and when you have a string that represents a javascript object in JSON format.

In the example you gave, your outer object looks like a javascript object, not a JSON string. So you don't need to parse it, you can just manipulate it. Embedded down inside it is an element named "text", which is JSON string. You can access the text element and then you can parse with JSON.parse. Here's an example (in which I cut out most of the extraneous content in your top level object):

const myObj = {"log": {
        "version": "1.2",
        "entries": [
            {
                "content": {
                    "size": 155,
                    "mimeType": "application/json",
                    "compression": 0,
                    "text": "{\"ip\":\"45.64.195.115\",\"ip_decimal\":759219059,\"country\":\"India\",\"country_eu\":false,\"country_iso\":\"IN\",\"city\":\"nocity\",\"latitude\":98.975,\"longitude\":92.8258}"
                }
            }
        ]
    }
};

const anotherObj = JSON.parse(myObj.log.entries[0].content.text);

console.log(JSON.stringify(anotherObj, null, 3));

This will produce the following output:

{
   "ip": "45.64.195.115",
   "ip_decimal": 759219059,
   "country": "India",
   "country_eu": false,
   "country_iso": "IN",
   "city": "nocity",
   "latitude": 98.975,
   "longitude": 92.8258
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM