0

I need to convert inlineScriptsTexts to object, because I need getting values from this. But I don't know, how to parse this string to object. [JSON.parse][1] does not work as expected. Is there some solution, which convert this string to object (like on image)?

img

window.onload = function() {
  let objExist = false;
  let inlineScripts = document.body;
  let inlineScriptsBlocks = Array.from(inlineScripts.getElementsByTagName('script'));
  inlineScriptsBlocks.forEach(scriptBlock => {
    let inlineScriptsTexts = scriptBlock.innerText;
    if (inlineScriptsTexts.includes('zvkDL')) {
      objExist = true;
      console.log(inlineScriptsTexts);
    }
  });

  //console.log(objExist);
}
zvkDL = {
            'language' : 'cs',
            'currency' : 'czk',
            'event': 'akurva',
            'ecommerce': {
                'purchase': {
                    'actionField': {
                        'id': 555,
                        'revenue': 535535,
                        'shipping': 3535,
                    }
                }
            },
            'eventCallback': function() {
                setGTMcookie( 555 ); // Jak se bude callback jmenovat nechám na vás. Jen to musí být srozumitelné. Pozor na scope JS callbacku.
            },
            'eventTimeout' : 2000,
            'eventCookie': { 'name': 'dasd', 'expires': 'asdsadd', 'value': 'funguje to', }
        };

2 Answers2

0

The method provided in JavaScript is eval - used to execute a string containing JavaScript source code.

JSON strings used to serialize a restricted set of data objects using text in "JavaScript Object Notation" can't be used in this case because JSON does not support serializing function objects.

There are two major alternatives to eval:

  1. Convert the text into a function by calling the global Function constructor, or
  2. Writing the text to a file on the server and downloading the file to a browser using <script> tags.

Calling eval or Function to execute code has a bad reputation and can be restricted in some code environments.

Before taking any of these approaches I would analyze the problem precisely: where is the string coming from, would it be better to solve the problem further up the source chain by creating a script in the first place, would cloning an existing source object without serializing it first be possible etc.

Also a note of caution if it applies: the textContent of an HTMLScriptElement can only be used to access the code if the element contains inline code. textContent will not return the code content of a downloaded script file.

traktor
  • 17,588
  • 4
  • 32
  • 53
0

So I tried to help

if (inlineScriptsTexts.includes('zvkDL '+'=')) {
  const str = inlineScriptsTexts.trim()
   .replace('zvkDL '+'=',"")
   .replace(/'/g,'"')
   .replace(/\/\/.*?\n/g,"")
   .replace(/\};/g,"}")
  console.log(str)
  console.log(JSON.parse(str));
}

But the function is a BIG problem

// the reason it won't work:
// this is as good as a representation of the object as can be made

const obj =  {
    "language": "cs",
    "currency": "czk",
    "event": "akurva",
    "ecommerce": {
      "purchase": {
        "actionField": {
          "id": 555,
          "revenue": 535535,
          "shipping": 3535,
        }
      }
    },
    "eventCallback": function() { setGTMcookie(555); }, // this will NOT be seen by JSON

    "eventTimeout": 2000,
    "eventCookie": {
      "name": "dasd",
      "expires": "asdsadd",
      "value": "funguje to",
    }
  }
  console.log(JSON.stringify(obj))

/*


window.onload = function() {
  let objExist = false;
  let inlineScripts = document.body;
  let inlineScriptsBlocks = Array.from(inlineScripts.getElementsByTagName('script'));
  inlineScriptsBlocks.forEach(scriptBlock => {
    let inlineScriptsTexts = scriptBlock.innerText;
    if (inlineScriptsTexts.includes('zvkDL '+'=')) {
      const str = inlineScriptsTexts.trim().replace('zvkDL '+'=',"").replace(/'/g,'"').replace(/\/\/.*?\n/g,"").replace(/\};/g,"}")
      console.log(str)
      console.log(JSON.parse(str));
    }
  });
}*/
<script>
  zvkDL = {
    'language': 'cs',
    'currency': 'czk',
    'event': 'akurva',
    'ecommerce': {
      'purchase': {
        'actionField': {
          'id': 555,
          'revenue': 535535,
          'shipping': 3535,
        }
      }
    },
    'eventCallback': function() {
      setGTMcookie(555); // Jak se bude callback jmenovat nechám na vás. Jen to musí být srozumitelné. Pozor na scope JS callbacku.
    },
    'eventTimeout': 2000,
    'eventCookie': {
      'name': 'dasd',
      'expires': 'asdsadd',
      'value': 'funguje to',
    }
  };
</script>
mplungjan
  • 169,008
  • 28
  • 173
  • 236