Content scripts are executed in an "isolated world" environment .
(内容脚本在“隔离的世界”环境中执行。)
You have to inject your state()
method into the page itself.(您必须将state()
方法注入页面本身。)
When you want to use one of the chrome.*
APIs in the script, you have to implement a special event handler, as described in this answer: Chrome extension - retrieving Gmail's original message .
(如果要在脚本中使用chrome.*
API之一,则必须实现特殊的事件处理程序,如以下答案中所述: Chrome扩展程序-检索Gmail的原始消息 。)
Otherwise, if you don't have to use chrome.*
APIs, I strongly recommend to inject all of your JS code in the page via adding a <script>
tag:
(否则,如果您不必使用chrome.*
API,我强烈建议通过添加<script>
标签将所有JS代码注入页面中:)
Table of contents(目录)
- Method 1: Inject another file
(方法1:注入另一个文件)
- Method 2: Inject embedded code
(方法2:注入嵌入式代码)
- Method 2b: Using a function
(方法2b:使用一个函数)
- Method 3: Using an inline event
(方法3:使用一个内联事件)
- Dynamic values in the injected code
(注入代码中的动态值)
Method 1: Inject another file(方法1:注入另一个文件)
This is the easiest/best method when you have lots of code.
(当您有很多代码时,这是最简单/最佳的方法。)
Include your actual JS code in a file within your extension, say script.js
.(将实际的JS代码包括在扩展名内的文件中,例如script.js
。)
Then let your content script be as follows (explained here: Google Chome “Application Shortcut” Custom Javascript ):(然后,让您的内容脚本如下所示(在此处进行说明: Google Chome“ Application Shortcut” Custom 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);
Note: If you use this method, the injected script.js
file has to be added to the "web_accessible_resources"
section ( example ).
(注意:如果使用此方法,则必须将注入的script.js
文件添加到"web_accessible_resources"
部分 ( 示例 )。)
If you do not, Chrome will refuse to load your script and display the following error in the console:(如果不这样做,Chrome会拒绝加载脚本并在控制台中显示以下错误:)
Denying load of chrome-extension://[EXTENSIONID]/script.js.
(拒绝加载chrome-extension:// [EXTENSIONID] /script.js。)
Resources must be listed in the web_accessible_resources manifest key in order to be loaded by pages outside the extension.(必须在web_accessible_resources清单键中列出资源,以便由扩展之外的页面加载。)
Method 2: Inject embedded code(方法2:注入嵌入式代码)
This method is useful when you want to quickly run a small piece of code.
(当您想快速运行一小段代码时,此方法很有用。)
(See also: How to disable facebook hotkeys with Chrome extension? ).((另请参见: 如何使用Chrome扩展程序禁用Facebook热键? )。)
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();
Note: template literals are only supported in Chrome 41 and above.
(注意: 模板文字仅在Chrome 41及更高版本中受支持。)
If you want the extension to work in Chrome 40-, use:(如果您希望扩展程序在Chrome 40-中运行,请使用:)
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('
');
Method 2b: Using a function(方法2b:使用一个函数)
For a big chunk of code, quoting the string is not feasible.
(对于一大段代码,引用字符串是不可行的。)
Instead of using an array, a function can be used, and stringified:(除了使用数组,还可以使用函数并对其进行字符串化:)
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();
This method works, because the +
operator on strings and a function converts all objects to a string.
(此方法有效,因为字符串和函数上的+
运算符会将所有对象转换为字符串。)
If you intend on using the code more than once, it's wise to create a function to avoid code repetition.(如果您打算多次使用该代码,则明智的做法是创建一个避免代码重复的函数。)
An implementation might look like:(一个实现可能看起来像:)
function injectScript(func) {
var actualCode = '(' + func + ')();'
...
}
injectScript(function() {
alert("Injected script");
});
Note: Since the function is serialized, the original scope, and all bound properties are lost!
(注意:由于该函数已序列化,因此原始作用域和所有绑定的属性都将丢失!)
var scriptToInject = function() {
console.log(typeof scriptToInject);
};
injectScript(scriptToInject);
// Console output: "undefined"
Method 3: Using an inline event(方法3:使用一个内联事件)
Sometimes, you want to run some code immediately, eg to run some code before the <head>
element is created.
(有时,您想立即运行一些代码,例如在创建<head>
元素之前运行一些代码。)
This can be done by inserting a <script>
tag with textContent
(see method 2/2b).(这可以通过插入来完成<script>
与标签textContent
(参见方法2 / 2B)。)
An alternative, but not recommended is to use inline events.
(一种替代方法, 但不建议使用内联事件。)
It is not recommended because if the page defines a Content Security policy that forbids inline scripts, then inline event listeners are blocked.(不建议这样做,因为如果页面定义了禁止内联脚本的内容安全策略,则内联事件侦听器将被阻止。)
Inline scripts injected by the extension, on the other hand, still run.(另一方面,由扩展名注入的内联脚本仍在运行。)
If you still want to use inline events, this is how:(如果您仍想使用内联事件,则可以这样:)
var actualCode = '// Some code example
' +
'console.log(document.documentElement.outerHTML);';
document.documentElement.setAttribute('onreset', actualCode);
document.documentElement.dispatchEvent(new CustomEvent('reset'));
document.documentElement.removeAttribute('onreset');
Note: This method assumes that there are no other global event listeners that handle the reset
event.
(注意:此方法假定没有其他全局事件侦听器来处理reset
事件。)
If there is, you can also pick one of the other global events.(如果存在,您还可以选择其他全局事件之一。)
Just open the JavaScript console (F12), type document.documentElement.on
, and pick on of the available events.(只需打开JavaScript控制台(F12),键入document.documentElement.on
,然后选择可用事件。)
Dynamic values in the injected code(注入代码中的动态值)
Occasionally, you need to pass an arbitrary variable to the injected function.
(有时,您需要将任意变量传递给注入的函数。)
For example:(例如:)
var GREETING = "Hi, I'm ";
var NAME = "Rob";
var scriptToInject = function() {
alert(GREETING + NAME);
};
To inject this code, you need to pass the variables as arguments to the anonymous function.
(要注入此代码,您需要将变量作为参数传递给匿名函数。)
Be sure to implement it correctly!(确保正确实施!)
The following will not work:(以下将无法正常工作:)
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)";
//