Contents
-
Manifest
- Include and exclude statements
-
Programmatic injection
- h3Name
-
The execution environment
- h3Name
-
Communicate with embedded pages
- h3Name
-
security
- h3Name
-
Reference files in the extension
- h3Name
-
example
- h3Name
-
Video (Youtube)
- h3Name
Content Scripts
Content scripts are javascript scripts that run inside a Web page. Using the standard DOM, they can get detailed information about the pages the browser visits and modify that information.
Here are some examples of what Content SciPT can do:
- Find urls from the page that are not written as hyperlinks and turn them into hyperlinks.
- Enlarge the page font to make the text clearer
- Find and work with microformats in the DOM
Of course, Content Scripts has some limitations. Some things they can’t do include:
- You cannot use chrome.* interfaces other than Chrome. extension
- Cannot access functions and variables defined in its extension
- Cannot access functions and variables defined in Web pages or other Content scripts
- Cross-site XMLHttpRequests cannot be done
These restrictions are not as bad as they seem. Content Scripts can use the Messages mechanism to communicate with the extension it is in, to indirectly use the Chrome.* interface, or to access extension data. Content Scripts can also communicate with Web pages through a shared DOM. For more information, see Execution Environment.
Manifest
If the content Scipt code always requires injection, you can register it in the content_scipt field in the Extension MANIFEST. Here’s an example:
{
"name": "My extension",
...
**"content_scripts": [
{
"matches": ["http://www.google.com/*"],
"css": ["mystyles.css"],
"js": ["jquery.js", "myscript.js"]
}
]**,
...
}
Copy the code
If injection is required only in certain cases, you can use the Permission field, as described in Programmatic Injection.
{
"name": "My extension",
...
**"permissions": [
"tabs", "http://www.google.com/*"
]**,
...
}
Copy the code
Using the content_scripts field, an extension can inject multiple content_script scripts into a page; Each Content Script can contain multiple javascript scripts and CSS files. Each entry in the content_script field can contain the following properties:
Name | Type | Description |
---|---|---|
matches |
array of strings | Must be.Define which pages need to be injected with content Script. To viewMatch PatternsFor detailed syntax. |
css |
array of strings | Optional.The CSS file that needs to be injected into the matching page. These files are injected in the order defined before the PAGE’s DOM tree is created and displayed. |
js |
array of strings | Optional.Javascript files that need to be injected into the page, in the order defined. |
run_at |
string | Optional.Control the timing of content Script injection. It can be document_start, document_end, or document_idle. By default, it is document_idle. If it is document_start, the file will be injected when all CSS is loaded, but the DOM is not created and no scripts are running. In the case of document_END, the file is injected immediately after the DOM is created, but before child resources such as images or frames are loaded. If it is document_idle, the browser will emit at document_end andwindow.onloadInjection at some point between events. The timing depends on the complexity of document loading and is optimized for faster page loading.Note:In the case of document_IDLE, the Content script does not necessarily receive the window.onload event, because it may not be loaded until after the event is emitted. In most cases, listening for the onload event in Content Script is unnecessary because the browser ensures that it is not executed until the DOM is created. If you must run it while window.onload is running, you can pass itdocument.readyStateProperty to check whether the onLoad event has been emitted. |
all_frames |
boolean | Optional.Controls whether to run in all frames of the matching page or only in the topmost frame. The default is false, which is to run only in the topmost frame. |
include_globs |
array of string | Optional.Controls which matching pages are injected with content_script. Emulate the @include keyword in Greasemonkey. Details can be found belowInclude and exclude globs. |
exclude_globs |
array of string | Optional.Controls which matching pages are injected with content_script. Emulate the @exclude keyword in Greasemonkey. Details can be found belowInclude and exclude globs. |
Include and exclude statements
A Content script can be injected only if the page URL matches any match pattern, matches any include glob pattern, and does not match any exclude glob pattern. Since the matches attribute is mandatory, include glob and exclude glob can only be used to limit which matched pages are affected.
In addition, these two properties have a different syntax than the Matches property and are more flexible. These two attributes can contain signs and? The symbol is used as a wildcard. Where strings of any length can be matched, and? Matches any single character.
For example, the statement “http://??? .example.com/foo/*”” matches all of the following:
- “www.example.com/foo/bar”
- “the.example.com/foo/”
But it does not match the following cases:
- “my.example.com/foo/bar”
- “example.com/foo/”
- “www.example.com/foo”
Programmatic injection
If you don’t need to inject javascript and CSS into every matching web page, you can control the injection of code programmatically. For example, you can inject a script only after the user clicks on a Browser Action icon.
To inject code into a page, the extension must have the cross-Origin permission and must be able to use the Chrome.tabs module. These permissions can be obtained by declaring them in the Permissions field of the manifest file.
Once permissions are set, javascript scripts can be injected with executeScript() calls. To inject CSS, insertCSS() is called.
The following code (see the example make_page_red) demonstrates the injection and execution of javascript code into a page with the current tag after clicking a button.
_/* in background.html */_
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript(null,
{code:"document.body.bgColor='red'"});
});
_/* in manifest.json */_
"permissions": [
"tabs", "http://*/*"
],
Copy the code
When the browser displays an HTTP web page and the user clicks the extension’s Browser Action button, the extension sets the bgColor property of the page to red. If the page does not set its background color with CSS, it will turn red.
In general, you can put the code in a file instead of injecting it directly as in the example above. It can be written like this:
chrome.tabs.executeScript(null, {file: "content_script.js"});
Copy the code
The execution environment
Content Scripts are run in a special environment called isolated World. They can access the DOM of the injected page, but not any javascript variables and functions inside. For each Content Script, it is as if no other script is running but itself. The reverse is also true: the javascript inside the page cannot access any variables and functions in the Content Script.
For example, this simple page:
hello.html
==========
<html>
<button id="mybutton">click me</button>
<script>
var greeting = "hello, ";
var button = document.getElementById("mybutton");
button.person_name = "Bob";
button.addEventListener("click", function() {
alert(greeting + button.person_name + ".");
}, false);
</script>
</html>
Copy the code
Now, inject the following script into hello.html:
contentscript.js
================
var greeting = "hola, ";
var button = document.getElementById("mybutton");
button.person_name = "Roberto";
button.addEventListener("click", function() {
alert(greeting + button.person_name + ".");
}, false);
Copy the code
Then, if you press the button, you can see both greetings at the same time.
The isolation environment allows a Content Script to modify its javascript environment without worrying about conflicts with other Content scripts on the page. For example, a Content script can contain JQuery v1 and a page can contain JQuery V2 without conflict between them.
Another important advantage is that the isolation environment can completely separate scripts on the page from scripts in the extension. This allows developers to provide more functionality in Content Script without having web pages take advantage of it.
Communicate with embedded pages
Although the execution environment of the Content Script is isolated from the page on which it is located, they share the DOM of the page. If a page needs to communicate with a Content Script (or with an extension via a Content Script), it must do so through this shared DOM.
The following example is implemented by customizing DOM events and putting data in a fixed place:
http://foo.com/example.html
===========================
var customEvent = document.createEvent('Event');
customEvent.initEvent('myCustomEvent', true, true);
function fireCustomEvent(data) {
hiddenDiv = document.getElementById('myCustomEventDiv');
hiddenDiv.innerText = data
hiddenDiv.dispatchEvent(customEvent);
}
Copy the code
contentscript.js
================
var port = chrome.extension.connect();
document.getElementById('myCustomEventDiv').addEventListener('myCustomEvent', function() {
var eventData = document.getElementById('myCustomEventDiv').innerText;
port.postMessage({message: "myCustomEvent", values: eventData});
});
Copy the code
In the above example, the HTML page (not an extension) creates a custom event that is activated and distributed when it writes event data to a specific element in the DOM. Content Script listens for this custom event on this particular element, gets data from this element, and posts a message to the extension process. In this way, the page establishes communication links with the extension. This method also applies to back communication.
security
There are two security issues you must be aware of when writing content Script. First, be careful not to introduce new security holes into the original page. For example, if the Content script is fetching data from another site (such as making an XMLHttpRequest call through the background page), it should be processed before injecting the data to prevent cross-site scripting attacks, Such as innerText injection instead of innerHTML injection. Be especially careful about retrieving HTTP content on an HTTPS page, as it could be corrupted in a man-in-the-middle manner.
Second, although the mechanism of running Content Script in a separate environment already provides some protection, indiscriminate use of content on a Web page can still be attacked by malicious Web pages.
contentscript.js
================
var data = document.getElementById("json-data")
// WARNING! Might be evaluating an evil script!
var parsed = eval("(" + data + ")")
contentscript.js
================
var elmt_id = ...
// WARNING! elmt_id might be "); ... evil script ... //"!
window.setTimeout("animate(" + elmt_id + ")", 200);
Copy the code
A more secure API is recommended:
contentscript.js
================
var data = document.getElementById("json-data")
// JSON.parse does not evaluate the attacker's scripts.
var parsed = JSON.parse(data)
contentscript.js
================
var elmt_id = ...
// The closure form of setTimeout does not evaluate scripts.
window.setTimeout(function() {
animate(elmt_id);
}, 200);
Copy the code
Reference files in the extension
Use chrome.extension.geturl () to get the URL of the file in the extension. You can use these urls just like any other, as shown in the following example:
_//Code for displaying <extensiondir>/images/myimage.png:</extensiondir>_
var imgURL = **chrome.extension.getURL("images/myimage.png")**;
document.getElementById("someImage").src = imgURL;
Copy the code
example
The example contentscript_xhr shows how an extension can make cross-site requests from a Content script. You can find more examples in the message Communication section of examples/ API/Messaging.
Look at the make_page_red and email_this_page examples for program injection.
For more examples and source code, see examples