Possiamo creare un'estensione Chrome con HTML, CSS e JavaScript.
Ogni estensione di Chrome ha una struttura specifica di file all’interno di una cartella:
Questo file descrive la tua estensione e contiene le informazioni essenziali per il browser
{
"manifest_version": 3,
"name": "La mia Estensione",
"version": "1.0",
"description": "Un'estensione Chrome di esempio.",
"action": {
"default_popup": "popup.html",
"default_icon": "icon.png"
},
"background": {
"service_worker": "service-worker.js"
},
"permissions": [
"storage",
"activeTab",
"scripting"
]
}
Il popup è ciò che appare quando clicchi sull'icona della tua estensione. Rappresenta il corpo della tua estensione come se fosse la pagina index.html di un sito.
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Estensione</title>
<!-- Collegamento del file CSS -->
<link rel="stylesheet" href="styles.css">
</head>
<body>
<h1>Benvenuto!</h1>
<button id="actionButton">Esegui Azione</button>
<!-- Collegamento a un file JS chiamato 'script.js' -->
<script src="script.js"></script>
</body>
</html>
Crea un file style.css per definire lo stile dell'estensione. Come visibile nell’esempio qui sopra il file style e collegato all’interno del file html.
body {
font-family: Arial, sans-serif;
padding: 10px;
width: 200px;
}
h1 {
color: #4CAF50;
}
button {
padding: 10px;
background-color: #4CAF50;
color: white;
border: none;
cursor: pointer;
}
Infine, puoi scrivere la logica per l'interazione in un file script.js.
Anche nel caso del file script questo è collegato sempre manualmente all’interno del file html.
document.getElementById('actionButton').addEventListener('click', () => {
alert('Azione eseguita!');
});
Sere per visualizzare l'icona della tua estensione nella barra degli strumenti.
Se vogliamo utilizzare un service worker per gestire il background (come richiesto da Manifest V3), specifichiamo il relativo file js nel campo background del del file manifest.json
Un service worker è uno script javascript eseguito su un thread separato rispetto a quello principlae che il browser esegue in background.
È una delle tecnologie chiave per le Progressive Web App (PWA), ma viene utilizzato anche nelle estensioni di Chrome (in particolare a partire da Manifest V3).
I service worker forniscono funzionalità avanzate come il caching, la sincronizzazione in background e la gestione delle notifiche push, anche quando la pagina o l'applicazione non è attiva.
Il service worker non ha accesso diretto al DOM della pagina e viene eseguito in un contesto separato in background. Questo significa che può essere utilizzato per eseguire attività come la gestione della cache o il recupero di dati dalla rete, anche quando la pagina non è aperta.
I service worker possono intercettare le richieste di rete della tua applicazione e rispondere con contenuti presi dalla cache o dalla rete stessa. Questo permette di creare esperienze offline o migliorare le performance caricando contenuti da una cache locale.
Il service worker reagisce a eventi come richieste di rete (fetch), messaggi in arrivo o sincronizzazioni in background.
Ecco alcuni eventi principali che un service worker può gestire:
I SW sono persistenti tra sessioni. Anche se l'utente chiude il browser, il service worker può continuare a funzionare in background per compiti specifici, come le notifiche push o la sincronizzazione dei dati.
I service worker funzionano solo su connessioni sicure (HTTPS), poiché hanno il potere di intercettare tutto il traffico di rete della tua app
Ecco un esempio base di un service worker che cache alcune risorse durante l'installazione e le serve dalla cache durante le richieste di rete:
// Versione della cache
const CACHE_NAME = 'v1';
// Risorse da mettere in cache
const ASSETS_TO_CACHE = [
'/',
'/index.html',
'/styles.css',
'/script.js',
'/icon.png'
];
// Evento di installazione
self.addEventListener('install', event => {
event.waitUntil(
caches.open(CACHE_NAME).then(cache => {
console.log('Aggiungo risorse alla cache');
return cache.addAll(ASSETS_TO_CACHE);
})
);
});
// Evento di fetch (intercetta le richieste di rete)
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request).then(response => {
// Se la risorsa è nella cache, la restituisco dalla cache
return response || fetch(event.request);
})
);
});
// Evento di attivazione
self.addEventListener('activate', event => {
// Rimuovo le vecchie cache
const cacheWhitelist = [CACHE_NAME];
event.waitUntil(
caches.keys().then(cacheNames => {
return Promise.all(
cacheNames.map(cacheName => {
if (!cacheWhitelist.includes(cacheName)) {
return caches.delete(cacheName);
}
})
);
})
);
});
Un service worker in una PWA è utilizzato principalmente per il caching delle risorse, la sincronizzazione in background, e le notifiche push. Lavora con l'obiettivo di migliorare l'esperienza utente offline e la performance generale.
Un service worker in un'estensione Chrome (Manifest V3) viene utilizzato per eseguire attività in background come la gestione delle schede, l'interazione con il browser e altre funzioni definite dall'estensione. Non gestisce direttamente il caching delle risorse come nelle PWA.
Di seguito i passaggi per caricare un'estensione chrome:
Le estensioni di Chrome non hanno accesso diretto agli elementi hardware del dispositivo, come il file system o le funzionalità di dispositivi mobili, allo stesso modo in cui una Progressive Web App (PWA) potrebbe fare.
Le PWA sono progettate per essere delle applicazioni web installabili con accesso a funzionalità native del dispositivo, come notifiche push, caching offline, accesso alla fotocamera, geolocalizzazione e altro, sfruttando le API web.
Tuttavia, ci sono alcune API che possiamo utilizzare per ottenere un comportamento simile anche per le estensioni di Chrome, ma con delle limitazioni.
Funzionalità del dispositivo:
Se desideri creare un'applicazione che possa accedere a elementi hardware del dispositivo, come fotocamera, microfono, o sistema di file, le PWA offrono un'ottima soluzione.
Ecco alcune funzionalità delle PWA con esempi di API:
navigator.mediaDevices.getUserMedia({ video: true, audio: true })
.then(stream => {
// Mostra il video in un elemento video
const video = document.querySelector('video');
video.srcObject = stream;
})
.catch(error => {
console.error('Errore nell'accesso alla fotocamera o microfono:', error);
});
async function openFile() {
const [fileHandle] = await window.showOpenFilePicker();
const file = await fileHandle.getFile();
const contents = await file.text();
console.log(contents);
}
navigator.geolocation.getCurrentPosition(position => {
console.log(`Latitudine: ${position.coords.latitude}, Longitudine: ${position.coords.longitude}`);
});
Notification.requestPermission().then(permission => {
if (permission === 'granted') {
new Notification('Notifica dalla tua PWA!');
}
});
Le API di Chrome per le estensioni permettono agli sviluppatori di interagire con il browser in modo avanzato, estendendone le funzionalità. Le estensioni di Chrome possono sfruttare queste API per interagire con le schede, modificare l’interfaccia utente, gestire la memoria, salvare dati localmente, comunicare con server remoti e molto altro.
Ecco una panoramica delle principali API offerte da Chrome per le estensioni.
L'API chrome.runtime è il cuore delle estensioni di Chrome. Gestisce il ciclo di vita dell'estensione e fornisce metodi per monitorare lo stato, comunicare tra componenti dell'estensione e ricevere informazioni sul contesto in cui è in esecuzione.
L'API chrome.tabs permette all'estensione di interagire con le schede del browser, come crearne di nuove, chiuderle, modificarle e ottenere informazioni sulle schede attualmente aperte.
L'API chrome.storage consente di salvare e recuperare dati localmente o in modo sincronizzato tra dispositivi. È utilizzata per memorizzare le preferenze dell'utente, dati di configurazione, o altri tipi di informazioni.
L'API chrome.bookmarks permette all'estensione di interagire con i segnalibri del browser, come creare, eliminare, modificare o recuperare i segnalibri.
L'API chrome.history permette di interagire con la cronologia di navigazione dell'utente. Puoi cercare elementi nella cronologia, recuperare dettagli delle visite e rimuovere voci specifiche.
L'API chrome.notifications consente all'estensione di mostrare notifiche all'utente. Puoi creare notifiche personalizzate con testo, immagini e pulsanti, e gestire eventi associati a tali notifiche.
L'API chrome.alarms permette di creare allarmi che eseguono determinate azioni a intervalli specifici o in un momento definito. Questo è utile per eseguire funzioni periodiche o per programmare attività a tempo.
L'API chrome.contextMenus consente di aggiungere voci personalizzate al menu contestuale (il menu che appare quando si fa clic con il tasto destro su una pagina o un elemento).
L'API chrome.webRequest permette di osservare, analizzare e potenzialmente modificare le richieste di rete che partono dal browser, come quelle per caricare una pagina o recuperare risorse.
L'API chrome.identity gestisce l'autenticazione degli utenti con l'account di Google. Può essere utilizzata per ottenere il token di accesso OAuth2 o per identificare l'utente.
L'API chrome.scripting (nuova in Manifest V3) è utilizzata per iniettare script nelle pagine web che vengono visualizzate nel browser. Permette di eseguire codice JavaScript in schede o finestre specifiche.
L'API chrome.permissions permette di richiedere o revocare autorizzazioni specifiche durante il funzionamento dell'estensione.
Questa API è stata introdotta con Manifest V3 per la gestione delle regole di rete e il blocco degli URL. Viene utilizzata per definire regole in modo dichiarativo per il blocco o il reindirizzamento di richieste di rete.
L'API chrome.cookies permette all'estensione di leggere, creare o rimuovere cookie dal browser.
L'API chrome.devtools permette di interagire con gli strumenti di sviluppo di Chrome (DevTools). Le estensioni possono aggiungere pannelli, sidebar e altre interfacce all'interno degli strumenti di sviluppo.
I Content Scripts sono file JavaScript che vengono eseguiti in un contesto isolato in una pagina web. Possono manipolare il DOM della pagina, leggere il contenuto della pagina e interagire con essa, ma non possono accedere direttamente agli oggetti JavaScript nativi della pagina (come window, document o variabili globali). Hanno, invece, accesso a un ambiente sicuro che consente loro di operare senza interferire con lo script della pagina.
I file content script possono essere iniettati automaticamente mediante il file manifest.json o manualmente mediante API Chrome
Nell’esempio che segue il Content Script content.js viene eseguito automaticamente su tutte le pagine il cui URL corrisponde al dominio example.com.
Possiamo anche specificare file CSS che verranno iniettati per modificare l’aspetto della pagina (styles.css).
{
"name": "Example Extension",
"version": "1.0",
"manifest_version": 3,
"permissions": ["tabs"],
"content_scripts": [
{
"matches": ["https://*.example.com/*"],
"js": ["content.js"],
"css": ["styles.css"]
}
]
}
I Content Scripts possono anche essere iniettati manualmente tramite API Chrome. Questo è utile quando vuoi iniettare il Content Script in risposta a un evento o un'azione specifica.
chrome.scripting.executeScript({
target: {tabId: tabId},
files: ['content.js']
});
I Content Scripts vengono eseguiti in un ambiente isolato. Questo significa che:
Esempio di come un Content Script può iniettare uno script nel contesto della pagina:
let script = document.createElement('script');
script.src = chrome.runtime.getURL('injected-script.js');
(document.head || document.documentElement).appendChild(script);
I Content Scripts non possono direttamente accedere agli altri script dell'estensione (ad esempio, il background script o popup), ma possono comunicare con essi utilizzando un sistema di messaggistica della API Chrome.
Esempio di invio di un messaggio dal Content Script al background script:
file content.js
chrome.runtime.sendMessage({greeting: "hello"}, function(response) {
console.log(response.farewell);
});
file service-worker.js
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if (request.greeting === "hello") {
sendResponse({farewell: "goodbye"});
}
});
Accesso limitato all’API di Chrome: I Content Scripts hanno accesso a un sottoinsieme ristretto delle API di Chrome. Non possono, ad esempio, usare API che richiedono permessi di alto livello, come chrome.tabs o chrome.windows
All’atto pratico dovremo avere questi file con qualcosa del genere all’interno:
Un file index.html con collegati un file script.js e un style.css
Il file script.js si occupa di gestire le interazioni con l’interfaccia dell’estensione stessa.
Quindi i click su eventuali bottoni ecc.
Un file manifest.json dove dichiariamo un service-worker e un content-script.
Ora, il compito di comunicare con una pagina che stiamo visualizzando, di fatto, è del content-script.js
Il nostro obiettivo è far dialogare script.js con content-script.js. in seguito a delle azioni sull’interfaccia dell’estensione.
Il content-script è l'unico che può eseguire delle azioni con la pagina corrente.
Possiamo comandarlo mediante uno scampio di messaggi tra script.js e lo stesso.
Il service-worker.js allo stato attuale lo utilizzeremo per far iniettare il content-script seppur potrebbe indurre errori in quanto in content-script nell’esempio che forniremo è già collegato mediante il file manifest.
Web scraping