( ) JavaScript
.
, JavaScript, Window extension.getBackgroundPage(). script, extension.getViews(), Window , , /, , , .
, , :
let backgroundPage = chrome.extension.getBackgroundPage();
chrome.webRequest.onBeforeRequest.removeListener(backgroundPage.example_callback);
, runtime.sendMessage(), runtime.onMessage / runtime.connect().
, , . , ? ? , () , script. - . , , .
:
- .
, options_ui, default_popup browser_action. :
- storage.local options.js. options.js
getOptions() background.js, script . - storage.local options.js. options.js
optionsUpdated script, . script . - A
optionsData options.js , data . .local script. script optionsStored options.js. options.js , .
, background.js options.js, , :
{
type:
data:
}
{
loggingUrls:
useDirect:
}
Firefox, Google Chrome:
manifest.json:
{
"description": "Demonstrate Changing webRequest.RequestFilter",
"manifest_version": 2,
"name": "webrequest.requestfilter-demo",
"version": "0.1",
"applications": {
"gecko": {
//Firefox: must define id to use option_ui:
"id": "webrequestrequestfilter-demo@example.example",
"strict_min_version": "42.0",
"strict_max_version": "51.*"
}
},
"permissions": [
"storage",
"webRequest",
"webRequestBlocking",
"<all_urls>" //Required for Google Chrome. Not, currently, needed for Firefox.
],
"background": {
"scripts": [
"background.js"
]
},
"browser_action": {
"default_icon": {
"48": "myIcon.png"
},
"default_title": "Currently NOT logging. Click to start logging only mozilla.org",
"browser_style": true,
"default_popup": "options.html"
},
"options_ui": {
"page": "options.html",
"chrome_style": true
}
}
background.js:
var webRequestExtraInfo = ["blocking"];
var useDirect=0;
const useDirectTypes=[ 'Directly invoke functions in background script'
,'Send a message that data was updated'
,'Send a message with all options data'];
chrome.runtime.onMessage.addListener(receiveMessage);
function receiveMessage(message,sender,sendResponse){
console.log('Received message: ',message);
if(typeof message !== 'object' || !message.hasOwnProperty('type')){
return;
}
if(message.type === "optionsUpdated"){
getOptions();
}
if(message.type === "optionsData"){
saveOptionsSentAsData(message.data,function(){
console.log('Sending response back to options page/panel');
sendResponse({type:'optionsStored'});
getOptions();
});
return true;
}
}
function getOptions(){
chrome.storage.local.get({
loggingUrls: [''],
useDirect: 0
}, function(items) {
if(typeof items.useDirect !== 'number' || items.useDirect<0 || items.useDirect>2) {
items.useDirect=0;
}
useDirect = items.useDirect;
updateLogging(items.loggingUrls);
console.log('useDirect=' + useDirectTypes[useDirect]);
});
}
function saveOptionsSentAsData(data,callback) {
chrome.storage.local.set(data, function() {
if(typeof callback === 'function'){
callback();
}
});
}
function updateLogging(urlArray){
if(typeof urlArray === "object" && Array.isArray(urlArray)
&& urlArray[0].length>0){
startListeningToWebRequests({urls: urlArray});
}else{
stopListeningToWebRequests();
}
}
function logURL(requestDetails) {
console.log("Loading: " + requestDetails.url);
return {};
}
function stopListeningToWebRequests() {
if(chrome.webRequest.onBeforeRequest.hasListener(logURL)) {
chrome.webRequest.onBeforeRequest.removeListener(logURL);
console.log("STOPPED logging all Web Requests");
}
}
function startListeningToWebRequests(requestFilter) {
stopListeningToWebRequests();
chrome.webRequest.onBeforeRequest
.addListener(logURL,requestFilter,webRequestExtraInfo);
console.log("Logging Web Requests:", requestFilter, "-->", requestFilter.urls);
}
getOptions();
var isChrome = !!chrome.extension.setUpdateUrlData
&& !!chrome.runtime.reload
&& !!chrome.runtime.restart;
if(!isChrome) {
window.alert('Open the console. isChrome=' + isChrome);
}
options.js:
function saveOptions(data, callback) {
chrome.storage.local.set(data, function() {
if(typeof callback === 'function'){
callback();
}
notifyOptionsSaved();
});
}
function optionsChanged() {
let loggingUrls = document.getElementById('loggingUrls').value;
let useDirectValue = document.getElementById('useDirect').value;
useDirectValue = +useDirectValue;
let optionData = {
loggingUrls: [loggingUrls],
useDirect: useDirectValue
}
if(useDirectValue == 0 ) {
saveOptions(optionData, function(){
let backgroundPage = chrome.extension.getBackgroundPage();
backgroundPage.getOptions();
});
} else if (useDirectValue == 1) {
saveOptions(optionData, function(){
chrome.runtime.sendMessage({type:'optionsUpdated'});
});
} else {
chrome.runtime.sendMessage({
type:'optionsData',
data: optionData
}, function(message){
if(typeof message === 'object' && message.hasOwnProperty('type')){
if(message.type === 'optionsStored') {
notifyOptionsSaved();
}
}
});
}
}
function useStoredOptionsForDisplayInDOM() {
chrome.storage.local.get({
loggingUrls: [''],
useDirect: 0
}, function(items) {
document.getElementById('loggingUrls').value = items.loggingUrls[0];
document.getElementById('useDirect').value = items.useDirect;
});
}
function notifyOptionsSaved(callback){
notifyStatusChange('Options saved.',callback);
}
function notifyStatusChange(newStatus,callback){
let status = document.getElementById('status');
status.textContent = newStatus;
setTimeout(function() {
status.textContent = '';
if(typeof callback === 'function'){
callback();
}
}, 1000);
}
document.addEventListener('DOMContentLoaded', useStoredOptionsForDisplayInDOM);
document.getElementById('optionsArea').addEventListener('change',optionsChanged);
options.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>WebRequest Logging Options</title>
<style>
body: { padding: 10px; }
</style>
</head>
<body>
<div id="optionsArea">
Log Web Requests from:
<select id="loggingUrls">
<option value="">None</option>
<option value="*://*.mozilla.org/*">Mozilla.org</option>
<option value="<all_urls>">All URLs</option>
</select>
<br/>
Communication with background page:
<select id="useDirect">
<option value="0">Direct</option>
<option value="1">Message Updated</option>
<option value="2">Message all Data</option>
</select>
</div>
<div id="status" style="top:0px;display:inline-block;"></div>
<script src="options.js"></script>
</body>
</html>
, , , OP , GitHub. options.js options.html , developer.chrome.com.