Nicht vom eigenen Server – wenn ein Plugin Scripts und Styles von einem CDN bezieht

803 6497
Foto von Gabriele Lässer

Hier handelt es sich um ein konkretes Fallbeispiel. Die Vorgehensweise sollte allerdings generell funktionieren, sofern Skripte und Stile korrekt eingebunden sind.

Es gibt Kunden, die wünschen sich kein Cookie-und Content-Blocker-Banner für ihre Website. Die Voraussetzung dafür sind einerseits allenfalls notwendige Cookies auf der Website zu verwenden, andererseits aber auch die Vermeidung des Ladens von Fremdinhalten. Letzteres hat nicht direkt etwas mit Cookies zu tun, und wird nach wie vor (jenseits von Google Fonts) leicht mal übersehen.

Verständlich, da es tatsächlich nicht immer einfach zu erkennen ist, wenn es die eigene Website betrifft, da man ja bei Besuch einer Website an der Oberfläche nicht erkennen kann, woher die Dateien die beteiligt sind, überhaupt kommen.

Endlich war die DSGVO-konforme bannerfreie Website fertig und geprüft. Dann sollte sie noch eine Timeline bekommen. Cool Timeline Pro wurde gekauft, installiert, eingerichtet, konfiguriert, dem Kunden gezeigt, und die Freude war groß. Meine hingegen weniger, denn auf der History-Seite hatten sich zwei „Fremddateien“ die über cdn.jsdelivr.net bereitgestellt waren, eingefunden.

Brauchte es also nun doch einen Contentblocker für Stil- und Skriptdatei? – Glücklicherweise in einem Fall wie diesem nicht. Ich kannte die Namen der betroffen Dateien und suchte sie im Quellcode des Plugins. Und da waren sie dann auch leicht zu finden.

wp_register_style( 'ctl_swiper_style', 'https://cdn.jsdelivr.net/npm/swiper@9/swiper-bundle.min.css', null, CTLPV, 'all' );
wp_register_script( 'ctl_swiper_script', 'https://cdn.jsdelivr.net/npm/swiper@9/swiper-bundle.min.js', array( 'jquery' ), CTLPV, false );

Die Quelle von Skripten und Stilen die über wp_register_style oder wp_register_script eingebunden werden, lässt sich einfach auf eine lokale Datei ändern.

Dafür die Dateien auf dem CDN aufrufen, und an einem Ort auf dem Server speichern, und über den Handler (resp. Namen, wie „ctl_swiper_script“) die neue URL als Quelle festlegen. In diesem Fall legte ich sie in die Assets des Themes.

function host_scripts_local() {
    $wp_scripts = wp_scripts();
    $wp_styles = wp_styles();

    if ( isset( $wp_scripts->registered['ctl_swiper_script'] ) ) {
        $wp_scripts->registered['ctl_swiper_script']->src = get_theme_file_uri('assets/js/swiper-bundle.min.js');
    }
	if ( isset( $wp_styles->registered['ctl_swiper_script'] ) ) {
        $wp_styles->registered['ctl_swiper_script']->src = get_theme_file_uri('assets/css/swiper-bundle.min.css');
    }
}
add_action( 'wp_enqueue_scripts', 'host_scripts_local', 11 );

Nun würde man so allerdings nie erfahren, wenn ein neues Sicherheits- oder Service-Release des Swiper Bundles V9 herauskäme, geschweige denn, davon partizipieren.

Die Lösung dafür: die Datei regelmäßig via Cronjob vom CDN herunterladen. Dafür wird eine PHP-Datei benötigt, die sich um den Download der Datei(en) kümmert. Zur Sicherheit wird beim Aufruf der PHP-Datei noch eine Zeichenfolge abgefragt. Sie kann Ziffern, Klein- und Großbuchstaben enthalten (mit Sonderzeichen funktionierte die Prüfung nicht). Auf diese Weise erhält nur der Cronjob Zugang zu der Datei.

$secret = $_GET['nounce'];
if ($secret !== 'sicherheitszeichenfolge') {
    header('HTTP/1.0 403 Forbidden');
    exit('Access denied.');
}

$external_files = array(
    array(
        'remotefile' => 'https://cdn.jsdelivr.net/npm/swiper@9/swiper-bundle.min.css',
        'localfile' => '/ganzer/pfad/wp-content/themes/theme-name/assets/css/swiper-bundle.min.css'
    ),
    array(
        'remotefile' => 'https://cdn.jsdelivr.net/npm/swiper@9/swiper-bundle.min.js',
        'localfile' => '/ganzer/pfad/wp-content/themes/theme-name/assets/js/swiper-bundle.min.js'
    ) 
);

foreach ( $external_files as $file ) {
	downloadFileIfModified($file);
}


function downloadFileIfModified( $file ) {
	$remoteFile = $file['remotefile'];
	$localFile  = $file['localfile'];

	$url  = $remoteFile; 
	$path = $localFile; 

	$fp = fopen( $path, 'w' );
	$ch = curl_init($url);
	curl_setopt($ch, CURLOPT_FILE, $fp);

	$data = curl_exec($ch);

	curl_close($ch);
	fclose($fp);
}

Anschließend einen Cronjob einrichen, der die PHP-Datei in regelmäßigen Anständen aufruft, z.B. wöchentlich, und die geheime Zeichenfolge als Parameter mit übergibt. https://url/mit/pfad/zur/downloadscriptdatei.php?nounce=sicherheitszeichenfolge

Soweit die prinzipielle Vorgehensweise. Die Downloadfunktion kann ggf. noch verfeinert werden, unter anderem mit einer Überprüfung, ob die Datei zwischenzeitlich verändert wurde etc. – die Funktionsfähigkeit einer erweiterten Download-Funktionalität lässt sich ja an einem ausgiebigeren Testszenario überprüfen.

Bitte Kommentarfunktion nicht für Supportanfragen nutzen. Dem kann hier nicht entsprochen werden. Die Angabe einer E-Mail-Adresse und eines Namens ist nicht erforderlich. Einen (Spitz)-Namen zu nennen wäre aber doch nett.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Hinweis: Sowohl angegebener Name als auch E-Mail-Adresse (beides ist optional, dafür werden alle Kommentare vor Veröffentlichung geprüft) werden dauerhaft gespeichert. Du kannst jeder Zeit die Löschung Deiner Daten oder / und Kommentare einfordern, direkt über dieses Formular (wird nicht veröffentlicht, und im Anschluss gelöscht), und ich werde das umgehend erledigen. – Mit hinterlassenen Kommentaren hinterlegte IP-Adressen werden nach zwei Monaten automatisch gelöscht

publicly queryable