In het manifest van een Chromium-extensie bepalen specifieke eigenschappen het gedrag, de compatibiliteit en de functionaliteit van de extensie binnen de browseromgeving. Deze eigenschappen zijn essentieel om te begrijpen omdat zij het raamwerk vormen waarbinnen extensies functioneren en interageren met de browser en gebruikers.

Een voorbeeld hiervan is de eigenschap requirements, die aangeeft welke browsertechnologieën noodzakelijk zijn om de extensie te kunnen draaien. Momenteel is “3D” de enige actief ondersteunde vereiste, waarbij bijvoorbeeld WebGL als feature wordt genoemd. Dit zorgt ervoor dat gebruikers met een apparaat dat niet over deze technologie beschikt, via de Chrome Web Store worden geïnformeerd dat hun apparaat niet compatibel is.

Een andere belangrijke eigenschap is sandbox, die bepaalt welke pagina’s binnen de extensie in een sandbox-omgeving worden geladen. Dit verhoogt de veiligheid door de pagina’s geïsoleerd te laten draaien, wat voorkomt dat kwaadaardige scripts buiten hun context schade aanrichten. Het is cruciaal dat ontwikkelaars zorgvuldig selecteren welke onderdelen van hun extensie in sandbox-modus moeten worden weergegeven, aangezien dit invloed heeft op de mate van bescherming en beperking van de functionaliteit.

Daarnaast speelt short_name een praktische rol in de gebruikerservaring. Dit is een verkorte naam van maximaal twaalf tekens die wordt gebruikt op plekken waar de volledige naam van de extensie te lang zou zijn, zoals in zijpanelen of de Omnibox. Hiermee blijft de interface overzichtelijk en wordt de herkenbaarheid van de extensie gewaarborgd zonder afbreuk te doen aan de branding.

Specifiek voor Chrome is er de eigenschap side_panel, waarmee een HTML-bestand kan worden opgegeven dat dient als inhoud voor een zijpaneel naast het actieve browsertabblad. Dit biedt een nieuwe dimensie voor extensies om informatie en functies aan te bieden zonder het hoofdvenster te verstoren. Deze instelling kan ook dynamisch aangepast worden via de WebExtensions API, wat ontwikkelaars flexibiliteit geeft in het gebruikersinterface-ontwerp.

Op het gebied van opslag definieert de storage-eigenschap het schema voor managed storage, die gebruikmaakt van de storage.managed API. Omdat browsers hier verschillende implementaties voor hanteren, is het noodzakelijk dat ontwikkelaars zich bewust zijn van de nuances per browser om compatibiliteit te waarborgen.

Een aantal eigenschappen zoals system_indicator en het gebruik van de update_url zijn respectievelijk gedeclareerd als deprecated of specifiek voor Chromium. Zo wordt de update_url automatisch beheerd door de Chrome Web Store bij extensies die daar gehost worden, wat zelfhosting van updates vereenvoudigt.

Voor versiebeheer zijn de eigenschappen version en version_name van belang. De eerste stelt het formele versienummer in, essentieel voor het onderscheiden van releases en het garanderen van compatibiliteit tussen browserupdates en extensieversies. Het is aan te raden om semantische versiebeheerstandaarden (semver.org) te volgen. De version_name biedt aanvullende informatie zoals “beta” of “rc1” die niet strikt aan de versienummeringsregels hoeft te voldoen maar wel extra context geeft over de status van de release.

De eigenschap web_accessible_resources is cruciaal om te begrijpen welke bestanden van een extensie toegankelijk zijn voor webpagina’s of andere extensies. Dit is een belangrijke veiligheidsmaatregel omdat standaard alle bestanden van een extensie afgeschermd zijn. Met deze instelling kan de ontwikkelaar selectief toegang geven tot bijvoorbeeld afbeeldingen, scripts of stylesheets, waarbij in Manifest V3 aanvullende toegangscontroles zijn toegevoegd, zoals het specificeren van toegestane origins via ‘matches’ of toegestane extensie-IDs.

Deze manifesteigenschappen zijn onlosmakelijk verbonden met het functioneren en de beveiliging van Chromium-extensies. Het is van belang dat ontwikkelaars niet alleen de syntaxis en mogelijke waarden begrijpen, maar ook de implicaties van elke eigenschap op compatibiliteit, beveiliging en gebruikerservaring. Vooral bij het migreren van oudere technologieën zoals Chrome Apps naar moderne extensies is inzicht in deze configuraties cruciaal.

Belangrijk is ook het besef dat veel eigenschappen specifiek zijn voor Chromium en dat er verschillen bestaan tussen browsers. Hierdoor dient men altijd rekening te houden met de context van de extensie en de doelgroep. Bovendien verandert het extensie-ecosysteem continu; properties kunnen worden afgevoerd, gewijzigd of uitgebreid. Actuele documentatie en richtlijnen dienen daarom continu geraadpleegd te worden om een toekomstbestendige en veilige extensie te ontwikkelen.

Verder is het essentieel te begrijpen dat manifestinstellingen niet alleen technische parameters zijn, maar ook impact hebben op de mate van vertrouwen en gebruiksvriendelijkheid voor de eindgebruiker. Goed gekozen eigenschappen kunnen de performantie verbeteren, het risico op kwetsbaarheden verkleinen en een positieve gebruikerservaring creëren, terwijl nalatigheid op dit vlak juist kan leiden tot afwijzing van extensies of veiligheidsproblemen.

Hoe werken achtergrondscripts en service workers in browserextensies?

Achtergrondscripts en service workers vormen de kern van moderne browserextensies, waarbij ze de functionaliteit en prestaties sterk beïnvloeden. De overgang van traditionele achtergrondscripts naar service workers markeert een fundamentele verschuiving in de architectuur van extensies, met name zichtbaar in de verschillen tussen Manifest V2 en Manifest V3.

Service workers zijn ontworpen als niet-persistente scripts die in de achtergrond draaien, maar alleen actief zijn wanneer ze nodig zijn. Dit in tegenstelling tot traditionele achtergrondscripts die continu actief kunnen blijven. Het niet-persistente karakter van service workers zorgt voor efficiënter geheugenbeheer en een kleinere impact op systeemprestaties. Echter, het betekent ook dat ze geen directe toegang hebben tot de DOM en beperkt zijn in het gebruik van globale API's, wat de manier waarop ze met de browser en webpagina's communiceren verandert.

Een belangrijk verschil tussen achtergrondscripts en service workers is dat service workers geen shutdown-event kennen en niet via programma’s expliciet kunnen worden afgesloten. Ze worden automatisch beëindigd wanneer ze niet meer nodig zijn, en kunnen weer worden gestart op basis van events. Dit vereist een andere benadering bij het ontwerpen van extensies, waarbij het beheer van status en communicatie tussen verschillende onderdelen zorgvuldig moet worden gepland.

Bij het ontwikkelen met service workers is het essentieel om te begrijpen hoe ze geïnspecteerd en gedebugd kunnen worden. Fouten in service workers kunnen anders zijn dan die in traditionele scripts, en hun automatische terminatie kan leiden tot onverwachte situaties als er geen rekening wordt gehouden met persistente opslag van gegevens en status.

Veelvoorkomende patronen in service worker-ontwikkeling omvatten het gebruik van event handlers voor het reageren op browsergebeurtenissen, veilige opslag en beheer van geheime gegevens en authenticatie, en het opzetten van message hubs voor communicatie tussen verschillende delen van de extensie. Ook het injecteren van scripts in webpagina's of het afluisteren van webverkeer vereist een nauwkeurige afstemming op het lifecycle-beheer van service workers.

Een ander relevant aspect is de manier waarop extensies omgaan met UI-componenten, zoals popup-vensters, optieschermen, en zijpanelen. Deze interfaces zijn vaak gekoppeld aan de achtergrondprocessen en vereisen een goede synchronisatie met de service worker, vooral omdat de worker niet altijd actief is. Het effectief managen van deze UI-elementen vraagt om een diepgaande kennis van het event-gedreven model en de beperkte mogelijkheden van service workers.

De overgang van Manifest V2 naar Manifest V3 heeft veel impact gehad op de ontwikkeling van extensies. Manifest V3 legt meer nadruk op veiligheid, privacy en performance, mede door het verplicht gebruik van service workers in plaats van achtergrondscripts. Dit betekent dat ontwikkelaars hun architectuur moeten herzien en aanpassen om te voldoen aan deze nieuwe standaarden.

Daarnaast is het cruciaal om rekening te houden met de beperkingen van service workers in het omgaan met bepaalde API's en functionaliteiten. De afwezigheid van toegang tot de DOM, bijvoorbeeld, dwingt ontwikkelaars tot een duidelijke scheiding tussen achtergrondlogica en UI-manipulatie, die vaak via content scripts verloopt.

Wat verder belangrijk is om te begrijpen, is dat service workers en achtergrondscripts geen statische componenten zijn; hun levenscyclus wordt dynamisch beheerd door de browser. Dit vereist dat extensie-ontwikkelaars mechanismen implementeren voor het opslaan van kritieke gegevens buiten het tijdelijke geheugen van de worker, zoals via opslag-API's. Dit voorkomt dat gegevens verloren gaan bij onverwachte beëindigingen.

Ten slotte is een diepgaand begrip van het event-gedreven model onontbeerlijk. Service workers reageren op een breed scala aan gebeurtenissen — van netwerkverzoeken tot gebruikersacties — en de programmering hiervan bepaalt de efficiëntie en betrouwbaarheid van de extensie.

Het is daarnaast belangrijk te beseffen dat de technische veranderingen ook gevolgen hebben voor de gebruikerservaring en het beveiligingsprofiel van extensies. Strengere permissions en de verminderde persistente achtergrondactiviteit helpen om extensies veiliger en minder resource-intensief te maken, maar vragen ook meer zorgvuldigheid bij het ontwerp en testen.

Hoe DeclarativeNetRequest API het gebruik van regels in browserextensies vereenvoudigt

De declarativeNetRequest (DNR) API wordt gepresenteerd als de opvolger van de webRequest API. Deze verschuiving in het ontwerp is een reactie op de behoefte aan een efficiënter, declaratief model waarbij de browser zelf de uitvoering van verzoeken regelt, in plaats van dat JavaScript zelf blokkades of wijzigingen aanbrengt in het netwerkverkeer. In plaats van het gebruik van JavaScript-functies om wijzigingen aan te brengen, definieer je nu de “instructies” voor elk verzoek in de vorm van een JSON-configuratieobject. Voor de meeste extensies is de DNR een effectieve vervanger voor de oude webRequest/webRequestBlocking mechanismen.

In de DNR API worden regels die betrekking hebben op netwerkverzoeken in twee hoofdtypes verdeeld: statische regels en dynamische regels. Beide vormen zijn bedoeld om verzoeken te blokkeren, om te leiden, of anderszins te beïnvloeden, maar het verschil zit in hoe en wanneer ze worden toegepast.

Permissies en toegang
De DNR API werkt met drie verschillende permissies:

  • De declarativeNetRequest-permissie stelt je extensie in staat om DNR-regels te definiëren, maar je hebt nog steeds hostpermissies nodig om regels toe te passen op specifieke domeinen.

  • De declarativeNetRequestWithHostAccess-permissie maakt het mogelijk om verzoeken te blokkeren of om te leiden op elk origine zonder expliciete hostpermissies.

  • De declarativeNetRequestFeedback-permissie is een aanvulling op de voorgaande permissies en biedt toegang tot functies die informatie teruggeven over de toegepaste regels.

Regelstructuur
Elke DNR-regel is een JSON-object. Er is altijd maar één regel per verzoek die van toepassing is binnen een extensie. De structuur van een regel bestaat uit:

  • id: een unieke, positieve integer die de regel identificeert.

  • priority: een optionele integer die aangeeft welke regel wordt toegepast wanneer meerdere regels matchen met een verzoek.

  • condition: een object dat de voorwaarden beschrijft voor de toepassing van de regel. Dit object kan domeinen, domeintypes, tabblad-ID’s en resource-types bevatten.

  • action: een object dat beschrijft wat de regel doet. De actie kan onder andere blokkeren, omleiden, toestaan, het upgraden van een URL-schema, het aanpassen van headers of toestaan van alle verzoeken omvatten.

Statische en dynamische regels
Er zijn twee manieren waarop regels gedefinieerd kunnen worden in DNR:

  • Statische regels worden gedefinieerd in JSON-bestanden en kunnen via de manifest.json van de extensie of via programmatische toevoeging worden geladen. Deze regels kunnen ingeschakeld of uitgeschakeld worden, maar ze kunnen alleen bestaan als onveranderlijke bestanden binnen de extensie. Statische regels hebben de beperking dat het aantal regels dat een extensie kan bevatten beperkt is door de browser.

  • Dynamische regels kunnen op elk moment worden toegevoegd, gewijzigd of verwijderd tijdens de uitvoering van de extensie. Deze regels kunnen tijdelijke regels zijn die alleen gelden voor de sessie waarin ze worden gedefinieerd.

Hoewel de DNR-regels in beide gevallen op dezelfde manier door de browser worden behandeld, is het belangrijk om te begrijpen dat dynamische regels interactiever zijn en meer flexibiliteit bieden, terwijl statische regels de voorkeur hebben wanneer consistente en voorgeconfigureerde blokkeringsmechanismen gewenst zijn.

Veilige versus onveilige regels
De regels binnen de DNR API kunnen worden verdeeld in "veilige" en "onveilige" regels:

  • Veilige regels zijn regels met acties zoals blokkeren, toestaan, of het upgraden van schema’s. Ze bieden voordelen zoals een hogere limiet op het aantal dynamische regels die kunnen worden aangemaakt (tot 30.000 in plaats van 5.000 voor onveilige regels).

  • Onveilige regels hebben acties zoals omleiden of het aanpassen van headers. Deze regels vereisen speciale aandacht omdat ze meer risico kunnen inhouden voor de netwerkbeveiliging.

Het is ook belangrijk te weten dat wanneer een extensie enkel veilige regels bijwerkt, deze updates geen goedkeuring van de browser vereisen en dus sneller gepubliceerd kunnen worden. Onveilige regels daarentegen, vereisen vaak een goedkeuringsproces omdat ze ingrijpender kunnen zijn voor de gebruikerservaring en netwerkbeveiliging.

Voorbeeld van statische regels
Om de werking van statische regels te begrijpen, kunnen we een voorbeeld bekijken van een extensie die afbeeldingen op Wikipedia blokkeert. In de manifest.json van deze extensie wordt een statische regelset gedefinieerd, die de regels vastlegt in een JSON-bestand:

json
{
"name": "Static DNR Example", "version": "0.0.1", "manifest_version": 3, "background": { "service_worker": "background.js", "type": "module" }, "declarative_net_request": { "rule_resources": [ { "id": "ruleset_1", "enabled": true, "path": "rules_1.json" } ] },
"permissions": ["declarativeNetRequest"],
"host_permissions": ["*://*.wikipedia.org/*", "*://*.wikimedia.org/*"] }

In dit voorbeeld zorgt de extensie ervoor dat, wanneer Wikipedia wordt geladen, de afbeeldingen worden geblokkeerd. Door op de extensieknop in de werkbalk van de browser te klikken, kan de gebruiker de regelset in- of uitschakelen, wat het mogelijk maakt om de afbeelding weer te laden.

Dynamische regels
Dynamische regels bieden meer flexibiliteit en kunnen tijdens de uitvoering van de extensie worden aangepast. Een voorbeeld hiervan is een dynamische regel die verzoeken om te leiden naar een specifiek bestand. In dit geval zou een afbeelding die geladen wordt van Wikipedia omgeleid kunnen worden naar een andere URL. Dit biedt een manier om gedrag dynamisch aan te passen op basis van de context of voorkeuren van de gebruiker.

Het gebruik van dynamische regels wordt doorgaans in situaties aangeraden waar snel reageren op verzoeken en flexibiliteit essentieel zijn. De extensie kan dan de regels toevoegen of verwijderen afhankelijk van de actie van de gebruiker of andere condities.

Samenvatting
Het begrijpen van de declarativeNetRequest API is essentieel voor iedereen die extensies ontwikkelt die netwerkverkeer willen beheren of manipuleren. Het biedt zowel statische als dynamische manieren om regels toe te passen die het gedrag van netwerkverzoeken bepalen. Het kennen van de verschillende permissies en het verschil tussen veilige en onveilige regels kan ontwikkelaars helpen bij het optimaliseren van hun extensies voor zowel snelheid als veiligheid.

Hoe inspecteer en ontwikkel je browserextensies effectief?

Bij het ontwikkelen van browserextensies is het cruciaal om inzicht te krijgen in de verschillende onderdelen en hun gedrag tijdens het debuggen en testen. Wanneer een extensie in de ontwikkelmodus geladen wordt, wordt de toestemmingsdialoog vaak uitgeschakeld om het proces te vereenvoudigen. Het pad van waaruit de extensie geladen wordt, toont de locatie in het bestandssysteem van het besturingssysteem, wat belangrijk is om te weten omdat alle bronbestanden direct vanuit deze directory worden geserveerd. Hierdoor zijn wijzigingen in deze bestanden onmiddellijk zichtbaar bij het herladen van de extensie.

De ontwikkelaarstools bieden uitgebreide mogelijkheden om verschillende onderdelen van een extensie te inspecteren. Zo kan via de optie “Inspect Views” de interface van bijvoorbeeld de opties-pagina geopend worden, waarbij zowel de console-uitvoer van het huidige tabblad als die van de achtergrond-serviceworker zichtbaar zijn. Indien gewenst kunnen de console-uitvoeren worden gefilterd om specifieke bronnen te onderscheiden, wat het debuggen aanzienlijk vergemakkelijkt.

Het inspecteren van de achtergrond-serviceworker vereist voorzichtigheid. Deze worker beïnvloedt namelijk de levenscyclus van de serviceworker door te voorkomen dat deze inactief wordt. Dit leidt ertoe dat de worker langer actief blijft dan normaal, wat onvoorspelbaar gedrag kan veroorzaken tijdens het debuggen. Het is daarom essentieel om het inspectievenster direct te sluiten nadat het gebruik voltooid is om interferentie te voorkomen. Voor een minder invasieve benadering biedt Google Chrome de pagina chrome://serviceworker-internals/ aan, waar realtime status en log-uitvoer van serviceworkers gevolgd kunnen worden zonder hun normale gedrag te verstoren.

Het combineren van console-uitvoer van content scripts en de webpagina kan verwarrend zijn, maar ook hier biedt de ontwikkelaarstool de mogelijkheid om te filteren op alleen de output van content scripts. Dit maakt het eenvoudiger om fouten en logs specifiek te analyseren.

Een ander belangrijk aspect is het herladen van extensies en hun componenten. Er zijn verschillende soorten herladen: het herladen van de gehele extensie, het herladen van extensiepagina’s zoals popups en opties, het herladen van webpagina’s met geïnjecteerde content scripts, en het herstarten van de ontwikkelaarstools zelf. Deze acties zijn noodzakelijk om wijzigingen in respectievelijk manifest.json, HTML/CSS/JS-bestanden, content scripts, en devtools-pagina’s door te voeren. Het forceren van een herlaad kan handmatig via de extensiepagina in Chrome, het verwijderen en opnieuw installeren van de extensie, of programmatisch met API-aanroepen zoals chrome.runtime.reload().

Foutbewaking tijdens de ontwikkeling vereist speciale aandacht. Fouten in HTML-interfaces worden zichtbaar in de reguliere console, terwijl alle fouten binnen de extensie samenkomen in een specifieke extensie-foutenweergave. Een fout die direct bij het opstarten van een serviceworker optreedt, verhindert de registratie ervan, waardoor event handlers niet zullen uitvoeren. Dit benadrukt het belang van grondige foutcontrole in het initiële gedeelte van serviceworker code.

Geautomatiseerd testen van browserextensies is mogelijk en lijkt sterk op het testen van gewone webpagina’s. Tools als Vitest en Puppeteer zijn populair om dergelijke tests te implementeren. Hoewel sommige onderdelen van extensies, zoals popups en content scripts, niet direct getest kunnen worden, zijn er werkbare oplossingen om toch een robuuste testset te creëren. Unit tests kunnen vrijwel identiek opgezet worden als voor webapplicaties, waarbij bijvoorbeeld React en Vitest als testomgeving fungeren. Hiermee wordt gegarandeerd dat onderdelen zoals popups correct functioneren en reageren op wijzigingen in de opslag-API.

Belangrijk om te beseffen is dat extensieontwikkeling niet alleen een kwestie is van code schrijven, maar ook van het begrijpen van de impact van de ontwikkelomgeving en het juiste gebruik van inspectie- en testtools. Het direct wijzigen van bronbestanden zonder een volledige herstart kan verwarring veroorzaken wanneer niet duidelijk is welke bestanden opnieuw geladen moeten worden. Daarnaast zorgt een open inspectievenster voor de achtergrondserviceworker soms voor onverklaarbare bugs. Daarom is het beheersen van de ontwikkelworkflow cruciaal voor efficiëntie en betrouwbaarheid.

Naast de technische aspecten verdient het ook aandacht hoe extensies omgaan met permissies en het manifest. De manifest.json is het centrale configuratiebestand dat alleen bij een volledige herlaad opnieuw ingelezen wordt. Begrijpen welke onderdelen direct door het systeem worden geladen en welke een herstart vereisen, is essentieel om verspillende handelingen te vermijden.

Ten slotte is het belangrijk om niet alleen naar de extensie zelf te kijken, maar ook hoe deze zich gedraagt in de context van de browser en de gebruiker. Bijvoorbeeld: achtergrondprocessen die blijven hangen door inspectievensters kunnen de performance beïnvloeden en leiden tot onverwachte gebruikerservaringen. Een grondige kennis van de lifecycle van serviceworkers en de manier waarop Chrome deze beheert helpt ontwikkelaars om robuuste, stabiele extensies te maken die soepel werken binnen het browserecosysteem.