Skrypty zawartości są wykonywane w środowisku „odizolowanego świata” . Musisz wstrzyknąć swoją state()
metodę do samej strony.
Jeśli chcesz użyć jednego z chrome.*
interfejsów API w skrypcie, musisz zaimplementować specjalną procedurę obsługi zdarzeń, zgodnie z opisem w odpowiedzi: Rozszerzenie Chrome - pobieranie oryginalnej wiadomości Gmaila .
W przeciwnym razie, jeśli nie musisz używać chrome.*
interfejsów API, zdecydowanie zalecamy wstrzyknięcie całego kodu JS na stronę poprzez dodanie <script>
tagu:
Spis treści
- Metoda 1: Wstrzyknięcie innego pliku
- Metoda 2: Wstrzyknięcie osadzonego kodu
- Metoda 2b: Korzystanie z funkcji
- Metoda 3: Wykorzystanie zdarzenia wbudowanego
- Wartości dynamiczne we wstrzykiwanym kodzie
Metoda 1: Wstrzyknięcie innego pliku
Jest to najłatwiejsza / najlepsza metoda, gdy masz dużo kodu. Powiedzmy, że dołączasz swój rzeczywisty kod JS do pliku w swoim rozszerzeniu script.js
. Następnie pozwól, aby Twój skrypt treści wyglądał następująco (wyjaśniono tutaj: Google Chome „Skrót aplikacji” Niestandardowy Javascript ):
var s = document.createElement('script');
// TODO: add "script.js" to web_accessible_resources in manifest.json
s.src = chrome.runtime.getURL('script.js');
s.onload = function() {
this.remove();
};
(document.head || document.documentElement).appendChild(s);
Uwaga: Jeśli używasz tej metody, wstrzyknięty script.js
plik należy dodać do "web_accessible_resources"
sekcji ( przykład ). Jeśli tego nie zrobisz, Chrome odmówi załadowania skryptu i wyświetli następujący błąd w konsoli:
Odmowa obciążenia rozszerzenia chrome: // [EXTENSIONID] /script.js. Zasoby muszą być wymienione w kluczu manifestu web_accessible_resources, aby mogły zostać załadowane przez strony spoza rozszerzenia.
Metoda 2: Wstrzyknięcie osadzonego kodu
Ta metoda jest przydatna, gdy chcesz szybko uruchomić mały fragment kodu. (Zobacz też: Jak wyłączyć klawisze skrótu Facebooka z rozszerzeniem Chrome? ).
var actualCode = `// Code here.
// If you want to use a variable, use $ and curly braces.
// For example, to use a fixed random number:
var someFixedRandomValue = ${ Math.random() };
// NOTE: Do not insert unsafe variables in this way, see below
// at "Dynamic values in the injected code"
`;
var script = document.createElement('script');
script.textContent = actualCode;
(document.head||document.documentElement).appendChild(script);
script.remove();
Uwaga: literały szablonów są obsługiwane tylko w Chrome 41 i nowszych wersjach. Jeśli chcesz, aby rozszerzenie działało w Chrome 40-, użyj:
var actualCode = ['/* Code here. Example: */' + 'alert(0);',
'// Beware! This array have to be joined',
'// using a newline. Otherwise, missing semicolons',
'// or single-line comments (//) will mess up your',
'// code ----->'].join('\n');
Metoda 2b: Korzystanie z funkcji
W przypadku dużej części kodu cytowanie ciągu nie jest możliwe. Zamiast używać tablicy, można użyć funkcji i skreślić:
var actualCode = '(' + function() {
// All code is executed in a local scope.
// For example, the following does NOT overwrite the global `alert` method
var alert = null;
// To overwrite a global variable, prefix `window`:
window.alert = null;
} + ')();';
var script = document.createElement('script');
script.textContent = actualCode;
(document.head||document.documentElement).appendChild(script);
script.remove();
Ta metoda działa, ponieważ +
operator ciągów i funkcja konwertuje wszystkie obiekty na ciąg. Jeśli zamierzasz używać kodu więcej niż jeden raz, dobrze jest stworzyć funkcję, aby uniknąć powtórzenia kodu. Implementacja może wyglądać następująco:
function injectScript(func) {
var actualCode = '(' + func + ')();'
...
}
injectScript(function() {
alert("Injected script");
});
Uwaga: Ponieważ funkcja jest serializowana, oryginalny zakres i wszystkie powiązane właściwości zostają utracone!
var scriptToInject = function() {
console.log(typeof scriptToInject);
};
injectScript(scriptToInject);
// Console output: "undefined"
Metoda 3: Wykorzystanie zdarzenia wbudowanego
Czasami chcesz uruchomić jakiś kod natychmiast, np. Aby uruchomić jakiś kod przed utworzeniem <head>
elementu. Można to zrobić, wstawiając <script>
znacznik za pomocą textContent
(patrz metoda 2 / 2b).
Alternatywą, ale niezalecaną, jest użycie zdarzeń wbudowanych. Nie jest to zalecane, ponieważ jeśli strona definiuje zasadę Content Security, która zabrania wbudowanych skryptów, wówczas wbudowane detektory zdarzeń są blokowane. Z drugiej strony skrypty wbudowane wstrzykiwane przez rozszerzenie nadal działają. Jeśli nadal chcesz korzystać ze zdarzeń wbudowanych, wykonaj następujące czynności:
var actualCode = '// Some code example \n' +
'console.log(document.documentElement.outerHTML);';
document.documentElement.setAttribute('onreset', actualCode);
document.documentElement.dispatchEvent(new CustomEvent('reset'));
document.documentElement.removeAttribute('onreset');
Uwaga: Ta metoda zakłada, że nie ma innych globalnych detektorów zdarzeń, które obsługiwałyby reset
zdarzenie. Jeśli tak, możesz wybrać jedno z innych wydarzeń globalnych. Wystarczy otworzyć konsolę JavaScript (F12), wpiszdocument.documentElement.on
i wybrać dostępne zdarzenia.
Wartości dynamiczne we wstrzykiwanym kodzie
Czasami musisz przekazać dowolną zmienną do wstrzykiwanej funkcji. Na przykład:
var GREETING = "Hi, I'm ";
var NAME = "Rob";
var scriptToInject = function() {
alert(GREETING + NAME);
};
Aby wstrzyknąć ten kod, musisz przekazać zmienne jako argumenty do funkcji anonimowej. Pamiętaj, aby poprawnie go wdrożyć! Następujące elementy nie będą działać:
var scriptToInject = function (GREETING, NAME) { ... };
var actualCode = '(' + scriptToInject + ')(' + GREETING + ',' + NAME + ')';
// The previous will work for numbers and booleans, but not strings.
// To see why, have a look at the resulting string:
var actualCode = "(function(GREETING, NAME) {...})(Hi, I'm ,Rob)";
// ^^^^^^^^ ^^^ No string literals!
Rozwiązaniem jest użycie JSON.stringify
przed przekazaniem argumentu. Przykład:
var actualCode = '(' + function(greeting, name) { ...
} + ')(' + JSON.stringify(GREETING) + ',' + JSON.stringify(NAME) + ')';
Jeśli masz wiele zmiennych, warto JSON.stringify
raz użyć , aby poprawić czytelność, jak następuje:
...
} + ')(' + JSON.stringify([arg1, arg2, arg3, arg4]) + ')';
player.addEventListener("onStateChange", state);