Загрузка внешнего JavaScript в расширение Google Chrome
Я пишу расширение Google Chrome, которое управляет текущей страницей (в основном добавляет кнопку).
В моем скрипте контента я хочу загрузить API Graph Facebook:
$fbDiv = $(document.createElement('div')).attr('id', 'fb-root');
$fbScript = $(document.createElement('script')).attr('src', 'https://connect.facebook.net/en_US/all.js');
$(body).append($fbDiv);
$(body).append($fbScript);
console.log("fbScript: " + typeof $fbScript.get(0));
console.log("fbScript parent: " + typeof $fbScript.parent().get(0));
console.log("find through body: " + typeof $(body).find($fbScript.get(0)).get(0));
Однако сценарий, похоже, не добавлен в body
, Вот консольный журнал:
fbScript: object
fbScript parent: undefined
find through body: undefined
Есть идеи, что я делаю не так?
2 ответа
Проблема заключается в том, что JavaScript внутри скриптов контента работает в собственной изолированной среде и имеет доступ только к другому JavaScript, который был загружен одним из двух способов:
Через манифест:
{
"name": "My extension",
...
"content_scripts": [
{
"js": ["https://connect.facebook.net/en_US/all.js"]
}
],
...
}
Или с помощью программной инъекции:
/* in background.html */
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript(null,
{file:"https://connect.facebook.net/en_US/all.js"});
});
Обязательно обновите ваши разрешения для манифеста:
/* in manifest.json */
"permissions": [
"tabs", "https://connect.facebook.net"
],
Добавление тега сценария фактически оценивает JavaScript в контексте содержащейся страницы за пределами изолированной программной среды JavaScript, к которой у вашего JavaScript есть доступ.
Кроме того, поскольку сценарий FB требует, чтобы в DOM был "fb-root", вам, вероятно, потребуется использовать программный подход, чтобы вы могли сначала обновить DOM с помощью элемента, а затем передать сообщение обратно на фоновую страницу, чтобы загрузите скрипт Facebook, чтобы он был доступен для JavaScript, который загружен в скрипты контента.
Расширения Google Chrome больше не позволяют вводить внешний код напрямую, однако вы все равно можете загрузить код с помощью вызова Ajax и передать его инжектору, как если бы он был блоком кода.
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
$.get("http://127.0.0.1:8000/static/plugin/somesite.js", function(result) {
chrome.tabs.executeScript(tabs[0].id, {code: result});
}, "text");
});
источник: /questions/4638857/rasshirenie-chrome-zagruzite-i-vyipolnite-vneshnij-skript/4638876#4638876
Если вы хотите загрузить его как сценарий содержимого:
fetch('https://example.com/content.js')
.then(resp => resp.text())
.then(eval)
.catch(console.error)
Если вы хотите загрузить его как фоновый скрипт. Возьмем, к примеру, https://example.com/bg.js.
- добавьте удаленный js-скрипт в файл фоновой страницы, который здесь называется background.html
<!DOCTYPE html>
<html>
<head>
<script src="https://example.com/bg.js"></script>
</head>
<body>
<div>Empty content</div>
</body>
</html>
- добавьте https://example.com в content_security_policy файла manifest.json:
"background": {
"page": "background.html"
},
"content_security_policy": "script-src 'self' https://example.com ; object-src 'self'",
Требования:
- Удаленный скрипт js должен обслуживаться через https вместо http.
- Вы должны указать страницу, а не массив скриптов в фоновом разделе