Signatur
Beschreibung
Das Ereignis beforescriptexecute ist ein nicht standardisiertes Ereignis, das nur Firefox (Gecko) unterstützt hat. Es wird am jeweiligen <script>-Element ausgelöst, direkt bevor dessen Code ausgeführt wird. Das Ereignis steigt im DOM auf (Bubbling). Deshalb registriert man den Listener meist zentral am document und liest das betroffene Skript über event.target aus.
Das Ereignis ist abbrechbar: Ruft der Handler event.preventDefault() auf, führt der Browser das Skript nicht aus. Das Gegenstück ist afterscriptexecute. Es wird ausgelöst, nachdem das Skript gelaufen ist.
Genutzt wurde das Ereignis vor allem in Browser-Erweiterungen, Userscripts (z. B. Greasemonkey) und für Diagnosezwecke: um Skripte von Drittanbietern zu blockieren, Ausführungszeiten zu messen oder Skripte gegen eigene Varianten auszutauschen. In der HTML-Spezifikation gab es das Ereignis nur vorübergehend. Es wurde wieder entfernt, und Chromium und WebKit haben es nie umgesetzt. In neuem Code sollte man es deshalb nicht verwenden. Moderne Alternativen sind document.currentScript, MutationObserver, Content Security Policy und Trusted Types.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignisname "beforescriptexecute". |
|
| $handler Pflicht | (event: Event) => void | Callback mit einem gewöhnlichen Event-Objekt. event.target ist das HTMLScriptElement, das gleich ausgeführt wird. Mit event.preventDefault() wird die Ausführung verhindert. |
|
| $options | boolean | AddEventListenerOptions | false | Die üblichen Optionen von addEventListener, z. B. { capture: true } oder { once: true }. |
Rückgabewert
addEventListener gibt nichts zurück. Das Ereignisobjekt ist ein einfaches Event mit bubbles: true und cancelable: true.Beispiele
Skripte von Drittanbietern blockieren (addEventListener)
// Muss so früh wie möglich registriert werden, z. B. im ersten <script> im <head>
const blockedHosts = ['tracker.example.com', 'ads.example.net'];
document.addEventListener('beforescriptexecute', (event) => {
const script = event.target;
if (!script.src) return; // Inline-Skripte zulassen
const { hostname } = new URL(script.src, location.href);
if (blockedHosts.includes(hostname)) {
event.preventDefault(); // Ausführung verhindern
console.warn(`Blockiert: ${script.src}`);
}
});
Ausführungszeit messen und Listener wieder entfernen
const starts = new WeakMap();
const onBefore = (e) => starts.set(e.target, performance.now());
const onAfter = (e) => {
const start = starts.get(e.target);
if (start === undefined) return;
const name = e.target.src || 'inline';
console.log(`${name}: ${(performance.now() - start).toFixed(1)} ms`);
};
document.addEventListener('beforescriptexecute', onBefore);
document.addEventListener('afterscriptexecute', onAfter);
// Nach dem Laden der Seite nicht mehr messen
window.addEventListener('load', () => {
document.removeEventListener('beforescriptexecute', onBefore);
document.removeEventListener('afterscriptexecute', onAfter);
});
Unterstützung prüfen und auf MutationObserver ausweichen
const supportsBSE = 'onbeforescriptexecute' in document;
if (supportsBSE) {
document.onbeforescriptexecute = (e) => {
console.log('Gleich wird ausgeführt:', e.target.src || 'inline');
};
} else {
// Browserübergreifend: neu eingefügte Skripte beobachten
// (hier nur beobachten, nicht zuverlässig verhindern)
new MutationObserver((mutations) => {
for (const m of mutations) {
for (const node of m.addedNodes) {
if (node.nodeName === 'SCRIPT') {
console.log('Skript eingefügt:', node.src || 'inline');
}
}
}
}).observe(document.documentElement, { childList: true, subtree: true });
}
// Wichtig · Fallstricke
- Nicht standardisiert und veraltet: Das Ereignis hat nur Firefox unterstützt. Chrome, Edge und Safari lösen es nie aus. Für Produktionscode ist es nicht geeignet.
- Nur klassische Skripte: Für
<script type=\"module\">wird das Ereignis nicht ausgelöst, ebenso wenig für Code auseval(),new Function(), Workern oder Event-Handler-Attributen wieonclick. - Reihenfolge: Der Listener greift nur für Skripte, die nach seiner Registrierung ausgeführt werden. Er muss also im allerersten Skript der Seite stehen.
- Keine Sicherheitsgrenze: Wer mit
preventDefault()Skripte blockiert, schafft keinen verlässlichen Schutz. Gegen eingeschleuste Skripte (XSS) helfen eine Content Security Policy (script-src) und Trusted Types. - Die Handler-Eigenschaft
onbeforescriptexecutewar nur in Firefox vorhanden.'onbeforescriptexecute' in documenteignet sich deshalb als grobe Prüfung, ob das Ereignis unterstützt wird. - Innerhalb eines laufenden Skripts liefert
document.currentScriptdas aktuelle<script>-Element. Das ist die standardisierte Alternative für viele Diagnosezwecke.