Динамически внедрить скрипты содержимого - Chrome Расширение - PullRequest
2 голосов
/ 05 марта 2020

Я пытаюсь создать расширение chrome, которое получает код javascript из бэкэнда и сохраняет его в localStorage (как base64), чтобы позже я смог внедрить его как скрипт содержимого, когда загружена нужная страница, работает большую часть времени, за исключением нескольких проблем ... Первая проблема (не очень важная) заключается в том, что я не могу получить доступ к Chrome API (например, chrome .storage или chrome .runtime.sendMessage), вторая проблема заключается в том, что он не внедряет правильный код в дочерние iframes ... потому что location.href возвращает URL верхней веб-страницы, и я не смог найти способ доступа к текущему URL iframe в самом iframe.

Это мой код:

манифест. json

//....
"content_scripts": [{
    "run_at": "document_end",
    "all_frames": true,
    "matches": [
        "<all_urls>"
    ],
    "js": [
        "src/inject/InjectManager.js"
    ]
}],
//...

InjectManager. js:

// Some functions were not included for brevity
chrome.runtime.sendMessage({ action: "get_supported_urls" }, function(supported_urls) {
    let current_url = window.location.href;

    // Check if we support current_url
    let js_code_to_inject = isWebsiteSupported(supported_urls, current_url); // this function returns string that is javascript code.
    if(js_code_to_inject){
        // Append the code to the body
        let script = document.createElement("script");
        script.type = "text/javascript";
        script.innerHTML = js_code_to_inject;

        document.body.appendChild(script);
    }
});

Как видите, я ' Это своего рода попытка воссоздать то, что chrome уже делает в манифесте. json 'content_script' раздел, потому что мой javascript код - Dynami c.

Примечание: я знаю, что это запрещено в chrome store и т. д., это расширение не должно быть передано никому.

Спасибо за чтение. Любая помощь будет принята с благодарностью.

1 Ответ

1 голос
/ 05 марта 2020

Я не могу получить доступ к Chrome API (например, chrome .storage или chrome .runtime.sendMessage)

Ваш код в настоящее время создает страницу скрипт , а не скрипт контента. Для последнего вам нужно использовать chrome.tabs.executeScript (см. Также документация к скрипту содержимого ) в фоновом скрипте.

location.href возвращает URL верхней веб-страницы, и я не могу Не можете найти способ доступа к текущему URL-адресу iframe внутри самого iframe.

Нет, то, что вы описываете, просто не может произойти, это было бы нарушением безопасности источника URL на уровне конца света, поэтому что-то еще происходит. Например, ваш манифест. json не имеет match_about_blank, что означает InjectManager. js вообще не обрабатывает динамически добавленные about:blank фреймы.


манифест. json :

"content_scripts": [{
  "match_about_blank": true,
  .....................

InjectManager. js:

chrome.runtime.sendMessage({ action: 'inject', data: location.href });

фоновый скрипт:

chrome.runtime.onMessage.addListener(({ action, data }, sender, sendResponse) => {
  if (action === 'inject') {
    chrome.tabs.executeScript(sender.tab.id, {
      code: getInjectionCode(data),
      frameId: sender.frameId,
    });
  }
});

Обратите внимание, что некоторые фреймы, такие как javascript: или srcdoc: выиграли вообще не запускайте скрипты содержимого в Chrome, поэтому вам придется обрабатывать их непосредственно в InjectManager. js, поскольку они не могут быть внедрены функцией executeScript (). Например, вы можете найти все iframe с помощью document.querySelectorAll('iframe') и создать элемент DOM script внутри, как вы делаете в настоящее время, но вы будете использовать frameElement.contentDocument вместо document и, конечно, вы проверите, является ли реальный URL-адрес iframe ( frameElement.contentWindow.location.href) не начинается с http, поскольку внутри кадров можно перемещаться без изменения их атрибута src снаружи. Выполните проверку внутри try / catch, потому что при доступе к iframe из другого источника будет возникать ошибка.

...