Можно ли получить доступ к значению из скрипта с помощью функции?

#javascript #google-tag-manager

Вопрос:

Мне нужно сохранить электронное письмо из этого скрипта:

 <script>
  window.renderOptIn = function() {
    window.gapi.load('surveyoptin', function() {
      window.gapi.surveyoptin.render(
        {
          "merchant_id": 0000,
          "order_id": "100101205",
          "email": "tester@example.com",
          "delivery_country": "XX",
          "estimated_delivery_date": "2021-09-03"
        });
    });
  }
</script>
 

Есть ли способ сделать это? Это физически заложено в коде, но я не могу придумать, как его получить.

Контекст:

Это связано с электронной коммерцией. Сценарий находится на странице «спасибо». Мне нужно сохранить электронное письмо в переменную, чтобы я мог использовать его для расширенного отслеживания конверсий Google.

Комментарии:

1. к чему именно вы пытаетесь получить доступ?

2. Если ваши gapi.surveyoptin открытые элементы переданы render , то да. Иначе — нет

3. Объект не виден за пределами функции, в которой он находится. На самом деле, он даже не виден внутри функции, так как он непосредственно передается в render() вызов. Таким образом, нет простого способа получить его. Вероятно, вы могли бы проанализировать тег сценария (нежелательно) или перезаписать render() метод (также нежелательно).

4. Единственный способ, о котором я могу подумать, — это регулярное выражение этого тега сценария, поскольку вы сказали, что он «физически присутствует в коде», я думаю, вы имеете в виду, что сценарий встроен.

5. Вы уверены, что электронная почта клиента жестко закодирована на вашем веб-сайте?

Ответ №1:

Доступ к документу.сценарии и фильтрация содержимого

Регулярное выражение или разделение.

 const code = [...document.scripts].filter(script => script.textContent.includes('surveyoptin'))
const match = code[0].textContent.match(/(?:render(.*s )({.*s ) /s)
const str = match[1].split(");")[0]; // forgot how to ignore trailing stuff after the group: );
console.log(str)
const obj = JSON.parse(str); // fails on 0000
console.log(obj.email)

// alternative - this is inflexible on spacing etc:

console.log(
  code[0]
  .textContent
  .split('"email": "')[1]
  .split('"')[0]
) 
 <script src="x.js"></script>
<script>const survey = "Survey"; // dummy script</script>
<script>
  window.renderOptIn = function() {
    window.gapi.load('surveyoptin', function() {
      window.gapi.surveyoptin.render(
        {
          "merchant_id": "0000",
          "order_id": "100101205",
          "email": "tester@example.com",
          "delivery_country": "XX",
          "estimated_delivery_date": "2021-09-03"
        });
    });
  }
</script> 

Комментарии:

1. Спасибо, особенно за 1-ю строку, которая может быть нацелена на правильный сценарий, даже если у нее нет никакого идентификатора , очень полезно. const code = [...document.scripts].filter(script => script.textContent.includes('surveyoptin')) Каким-то образом весь ваш сценарий не работал , когда я запустил его на странице (что привело к синтаксической ошибке: неожиданный токен в JSON в JSON.parse ), но я синтезировал ваше решение с решением @rahul-shah, и оно сработало. Большое спасибо!

2. 0000 — это недопустимый номер, так что его нужно как-то решить

Ответ №2:

Таким образом, вы можете получить доступ к тегу сценария с помощью селектора запросов. Было бы идеально, если бы вы могли прикрепить идентификатор к тегу сценария, чтобы вы могли легко его получить. Если нет, то для этого тоже есть обходной путь.

Вы можете получить доступ к содержимому тега сценария с помощью element.innerHTML. Затем вам придется применить регулярное выражение или манипуляции со строками, чтобы получить точный фрагмент, который вы ищете. Например.

 const script = document.querySelector("#script_id")
const scriptText = script.innerText
const emailString = scriptText.match(/"email":.*,/)[0]
const email = emailString.split(":")[1].trim().replace(/[,(\")]/g,"")
 

Это работает. Возможно, вам придется немного изменить функции синтаксического анализа. Но я надеюсь, что подход ясен

P.S. Это очень хакерский способ сделать это, и такого кода следует избегать, насколько это возможно. Но если тебе придется это сделать, я не могу придумать другого способа.