Как получить доступ к переменным или функциям кода сайта из расширения браузера

233
11 марта 2018, 22:09

Есть некий сайт: example.com на нем определенный скрипт:

var a = 99;
function site_func () {
console.log ( 'a');
}

Я хочу создать расширение, где будет мой код, но мне нужно взять значение переменной (может быть абсолютно любая переменная), или выполнить любую функцию типа site_func, но если это сделать из расширения, то выдаст ошибку что такая функция не существует, как сделать так чтобы мой скрипт выполнил именно функцию с сайта?

Answer 1

Из соображений безопасности код расширения браузера работает в специальной "песочнице", из которой он имеет полный доступ к DOM сайта, но не имеет доступа к переменным и функциям JS-кода на сайте.

Это ограничение можно обойти, внедрив свой код непосредственно в страницу сайта, используя функции DOM. (Но не удивляйтесь, если приложение использующее подобные механизмы не будет опубликовано на Web Store).

Пример использования (пишется в content-скрипте расширения) (на примере расширения chrome, в других браузерах возможно использование примерно такой же техники):

  // Создаем на странице невидимый элемент div, через который мы сможем обмениваться данными
  var div=document.createElement("div");
  div.id="xgp_msg";
  div.style.display='none';
  document.body.appendChild(div);
  // Создаем обработчик собственного события
  // (событие будет исполняться в контексте расширения !)
  div.addEventListener("xgpEvent", function(event) {
    var msg;
    // Пробуем получить и распарсить данные, содержащиеся в нашем div
    try {msg=JSON.parse(event.target.innerText);} catch(e) {
      // Тут хорошо бы ошибки куда нибудь вывести
    };
    if(!msg) return;
    console.log(msg);
    // Тут можем использовать данные, полученные со страницы
  });
  // Создаем на странице (в контексте сайта) новый скрипт:    
  var script = document.createElement('script');
  // Задаем его текст
  script.textContent = "var xgp_event=document.createEvent('Event');"+
                       "xgp_event.initEvent('xgpEvent',true,true);"+
                       "function xgp_send(msg) {"+
                       " var d=document.getElementById('xgp_msg');"+
                       " d.innerText=JSON.stringify(msg);"+
                       " d.dispatchEvent(xgp_event);"+
                       "}"+
                       // Далее мы можем создавать на странице другие сприпты
                       // которые могут в контексте сайта вызывать передачу сообщения
                       // в расширение. Например можно дописать прямо тут:
                       "xgp_send({ var_a: a,"+
                       "           func_result: site_func()"+
                       "});";
  // Включаем созданный скрипт в DOM документа
  (document.head||document.documentElement).appendChild(script);
  // В этот момент созданный скрипт исполняется в контексте сайта
  // Сразу после этого он уже не нужен в DOM и его можно удалить
  // (при этом функция xgp_send() останется и её можно будет вызывать из контекста сайта)
  script.remove();

Внимание: некоторые сайты могут запретить политикой безопасности даже включение произвольного кода в страницу и тогда данный метод может не сработать.

Если требуется просто выполнить функцию сайта и нам не нужен ее результат, можем ограничится созданием элемента <script> с текстом ее вызова. И не заморачиваться с созданием и вызовом событий.

Answer 2

Если говорить про расширения Firefox: расширения там могут всё тоже самое, что .exe приложения в windows, и даже больше - сообщения безопасности на их деятельность всплывать не будут. Ограничения безопасности если есть, то обходятся все. Ведь можно даже подключать .dll и использовать библиотеки функций прямо из JS. Единственное НО - простой пользователь не сможет установить ваше расширение, пока оно не пройдёт проверку на firefox addonns, или пока не установит firefox developer edition и отключит подпись расширений.

К чему это я - вероятно вам нужны расширения для управления сайтами (боты, упрощение деятельности пользователей, иная автоматизация). Для этих целей Firefox идеален, и в IT-компаниях часто есть бот-машина с ним(и внутренними ботами компании). Такая задача, как выполнить функцию сайта, решается просто, в одну строчку:

var result = content.document.defaultView.wrappedJSObject.site_func();
//где content.document - документ текущей открытой вкладки

Например вывод объекта в консоль текущей открытой страницы и затем строки "HelloWorld!" туда-же:

content.document.defaultView.wrappedJSObject.console.log(ExtInternalObject, "HelloWorld!");

Этот ответ - больше наводка, только один wrappedJSObject это часть талмудов концепций фаерфокса , с множеством неизвестных простому web-еру терминов

READ ALSO
Удалить сохранённые данные

Удалить сохранённые данные

Я добавил к формам ввода autocomplete="off", но сохранённые данные(логин и пароль) все равно отображаются в этих формахКак устранить данную проблему?

191
Как заменить скрытую ссылку?

Как заменить скрытую ссылку?

Всем здрасьтеСкачал шаблон, в нем где-то в скрипте есть скрытая ссылка на адрес

136
Меняем картинку чекбоксами

Меняем картинку чекбоксами

Есть главная картинка 1png и 2 чекбокса

149
Автоматически поставить ссылку

Автоматически поставить ссылку

У меня есть список новостейЯ хочу, чтобы ссылка в тексте новости автоматически обозначалась между тегами

190