Можно ли изменить объект окна из расширения Chrome?

Я хотел бы сделать расширение Chrome, которое предоставляет новый объект внутри window. Когда веб-страницу просматривается в браузере с загруженным добавлением, я хотел бы, чтобы window.mything был доступен через Javascript. Объект window.mything будет иметь некоторые функции, которые я буду определять в расширении, и эти функции должны быть вызваны из console.log или любого файла Javascript, когда страница просматривается в браузере с включенным расширением.

Мне удалось успешно вставить Javascript файл на страницу с помощью Содержимое Script:

var s = document.createElement("script"); 
s.src = chrome.extension.getURL("mything.js");
document.getElementsByTagName("head")[0].appendChild(s);

mything.js выглядит следующим образом:

window.mything = {thing: true};
console.log(window);

Всякий раз, когда загружается страница, я вижу весь объект window, поскольку я ожидаю, что он будет в консоли. Однако я не могу взаимодействовать с объектом window.mything с консоли. Кажется, если введенный script не изменил глобальный объект window.

Как изменить глобальный объект window из расширения Chrome?

Ответы

Ответ 1

Вы не можете, а не напрямую. Из документации по сценариям контента:

Однако сценарии содержимого имеют некоторые ограничения. Они не могут:

  • Использовать хром. * API (за исключением частей chrome.extension)
  • Использовать переменные или функции, определенные их страницами расширения
  • Использовать переменные или функции, определенные веб-страницами или другими сценариями контента

(выделено курсивом)

Объект window, который видит контент script, - это не тот объект window, который видит страница.

Вы можете передавать сообщения через DOM, используя метод window.postMessage. Ваша страница и контент script прослушивают событие сообщение, и всякий раз, когда вы вызываете window.postMessage из одного из этих мест, другой получит его. Там пример этого на странице документации "Скрипты содержимого".

изменить: Вы могли бы добавить некоторые методы на страницу, введя script из содержимого script. Он все равно не сможет связаться с остальной частью расширения, хотя, не используя что-то вроде postMessage, но вы могли бы хотя бы добавить некоторые вещи на страницу window

var elt = document.createElement("script");
elt.innerHTML = "window.foo = {bar:function(){/*whatever*/}};"
document.head.appendChild(elt);

Ответ 2

Я играл с этим. Я обнаружил, что могу взаимодействовать с окном объекта браузера, обернув свой javascript в window.location = call.

var myInjectedJs = "window.foo='This exists in the \'real\' window object';"
window.location = "javascript:" + myInjectedJs;

var myInjectedJs2 = "window.bar='So does this.';"
window.location = "javascript:" + myInjectedJs2;

Он работает, но только для последнего экземпляра window.location. Если вы обращаетесь к объекту окна документа, он будет иметь переменную "bar", но не "foo"

Ответ 3

Скрипты содержимого могут вызывать методы window, которые затем могут использоваться для изменения объекта window. Это проще, чем <script> вставка тегов и работает даже тогда, когда <head> и <body> еще не были проанализированы (например, при использовании run_at: document_start).

// In Content Script
window.addEventListener('load', loadEvent => {
    let window = loadEvent.currentTarget;
    window.document.title='You changed me!';
});

Ответ 4

Расширение chrome content_script выполняется в пределах своего собственного контекста, который отделен от окна. Вы можете ввести script на страницу, хотя она работает в том же контексте, что и окно страницы, например: Расширение Chrome - получение глобальной переменной с веб-страницы

Мне удалось вызвать методы на объекте окна и изменить свойства окна, по существу добавив script.js к странице DOM:

var s = document.createElement('script');
s.src = chrome.extension.getURL('script.js');
(document.head||document.documentElement).appendChild(s);
s.onload = function() {
    s.remove();
};

и создания пользовательских прослушивателей событий в этом файле script:

document.addEventListener('_my_custom_event', function(e) {
  // do whatever you'd like! Like access the window obj
  window.myData = e.detail.my_event_data;
})

и отправив это событие в content_script:

var foo = 'bar'
document.dispatchEvent(new CustomEvent('_save_OG_Editor', {
  'detail': {
    'my_event_data': foo
  }
}))

или наоборот; отправлять события в script.js и прослушивать их в своем расширении content_script (как показано на приведенной выше ссылке).

Просто добавьте введенный script в файлы расширений и добавьте путь к файлу script в манифест в "web_accessible_resources" или вы получите сообщение об ошибке.

Надежда, которая помогает кому-то\(• ◡ •)/