tas2580
Blog über Webentwicklung

Externe Ressourcen auf HTTPS Seiten ohne Warnung einbinden

tas2580  

Wenn man eine Webseite über HTTPS aufruft sollten auch alle eingebundenen Ressourcen über HTTPS eingebunden werden da der Browser sonst eine Warnung in der URL Leiste anzeigt oder die Ressource blockiert und gar nicht anzeigt. Leider ist es nicht immer möglich alle externen Ressourcen die man einbinden möchte auch über HTTPS zu bekommen. Mit einem kleinen Trick kann man aber trotzdem erreichen das es zu keiner Warnung kommt.


Beim einbinden von externen Ressourcen sollte man unbedingt das Urheberrecht beachten!

Ein weiterer Vorteil ist, dass so keine Nutzerdaten an den Server von dem man die Ressourcen aus einbindet weitergegeben werden, das verbessert den Datenschutz für seine Besucher.

Bilder einbinden

Man muss einfach nur die externe URL über ein lokales Script aufrufen dann macht der Server den unsicheren Aufruf und liefert den Inhalt über HTTPS an den Besucher aus. Man erstellt sich also eine PHP-Datei mit folgendem Inhalt:

<?php
$url 
= isset($_GET['url']) ? $_GET['url'] : '';
if(
$url)
{
    
$header get_headers($urltrue);
    
header('Content-type: ' $header['Content-Type']);
    echo 
file_get_contents($url);
}

Das Script holt sich den Header der Datei die man einbinden möchte um den Content-type festzustellen und ihn für sich selber auszugeben. Dann holt es den Inhalt der Datei und gibt ihn aus.

Wenn man jetzt z.B. ein Bild hat das unter http://example.com/bild.jpg erreichbar ist bindet man es in seine Seite mit <img src="./image.php?url=http://example.com/bild.jpg" /> ein. Die Datei wird vom Webserver geladen und über eine lokale URL 1 zu 1 wieder ausgegeben. Der Browser bezieht die Ressource jetzt also vom Webserver über HTTPS und zeigt keine Warnung mehr an.

Damit man die externe Ressource nicht jedes mal neu holen muss kann man sie auch lokal zwischenspeichern, dabei muss man aber aufpassen das man den Inhalt der Datei nicht einfach so auf dem eigenen Server speichert da man sich sonst evtl. bösartigen Code einfängt der lokal ausgeführt werden kann wenn man die URL zur Cache-Datei kennt. Um das zu verhindern kann man den Inhalt der Datei einfach mit Base64 Kodieren und beim ausgeben wieder Decodieren.

<?php
$url 
= isset($_GET['url']) ? $_GET['url'] : '';
if(
$url)
{
    
$cachefile 'cache/' md5($url);
    if(
file_exists($cachefile))
    {
        
$data file_get_contents($cachefile);
        
$data base64_decode($data);
        
$finfo = new finfo(FILEINFO_MIME_TYPE);
        
$type $finfo->buffer($data);
        
header('Content-type: ' $type);
        echo 
$data;
    }
    else
    {
        
$data file_get_contents($url);
        
$handle fopen($cachefile'w');
        
fwrite($handlebase64_encode($data));
        
fclose($handle);
        
$header get_headers($urltrue);
        
header('Content-type: ' $header['Content-Type']);
        echo 
$data;
    }
}

Hier wird der MD5 Hash der URL als Dateiname für den Cache verwendet und geprüft ob die Datei im Cache existiert. Wenn sie vorhanden ist wird sie von lokal geladen, dekodiert, der Mime Type ausgelesen und ausgegeben. Wenn die Datei im Cache nicht existiert wird sie geladen, lokal gespeichert und ausgegeben.

Komplette Seiten einbinden

Das Script oben funktioniert wunderbar mit einzelnen Dateien wie Bildern, aber wenn man komplette HTML Seiten per IFrame einbinden möchte gibt es noch einiges mehr zu beachten. Innerhalb der HTML Datei können weitere Ressourcen wie CSS eingebunden sein die dann auch wieder über HTTPS ausgeliefert werden müssen. Außerdem müssen relative Links in absolute umgeschrieben werden da sie sonst ungültig werden, hier wird die Sache also etwas komplizierter. Aber auch das ist machbar:

<?php
$url 
= isset($_GET['url']) ? $_GET['url'] : '';
if(
$url)

    
$url_parts parse_url($url);
    
/* Get the full URL as base and set this script bevor, because we need to load embedded files over this script */
    
$base_url 'https://' $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'] . '?url=' $url_parts['scheme'] . '://' $url_parts['host'];

    
/* Split the path in parts */
    
$path preg_split('#/#'dirname($url_parts['path']));

    
/* Generate array to map relative URLs into absolute URLs */
    
$replace_last $base_url;
    
$search[] = './';
    foreach(
$path as $i => $a)
    {
        
$search[] = $search_last $search_last '../';
        
$replace[] = $replace_last $replace_last $a '/';
    }    
    
/* Remove the last */
    
array_pop($search);
    
/* And reverse it */
    
$search array_reverse($search);

    
/* Get the header and send correct content type */
    
$header get_headers($urltrue);
    
header('Content-type: ' $header['Content-Type']);

    
/* Get the content */
    
$content file_get_contents($url);

    
/* Replace relative URLs with absolute URLs */
    
$content str_replace($search$replace$content);

    
/* Output the content */
    
echo $content;
}

Das Script erkennt die Verzeichnistiefe der eingebundenen Datei und ersetzt alle ../ durch den entsprechenden Ordnernamen. Vor jeden relativen Link wird die Domain angehängt und das alles wird wiederum über das Script geladen um unsichere Ressourcen zu unterbinden.


Ähnliche Beiträge


Kommentare

Hallo, ich bin ein ziemlicher Neuling was HTML und so weiter angeht. Daher komme ich auch mit der Anleitung nicht ganz zurecht...ich habe dieses "lokale Skript in meine Seite kopiert und darunter dann per iframe den link zur externen Seite. Allerdings wird auf meiner Homepage nichts angezeigt...habe ich da was falsch gemacht?

<?php
$url = isset($_GET['url']) ? $_GET['url'] : '';
if($url)
{
    $header = get_headers($url, true);
    header('Content-type: ' . $header['Content-Type']);
    echo file_get_contents($url);
}

<iframe src="http://www.linkzurexternenseite"></iframe>


vielen Dank im Voraus!

Du musst als URL für den IFrame das Script angeben und dem als Parameter die URL die du einbinden möchtest.
Wenn du den PHP Code unter script.php gespeichert hast musst du den IFrame folgendermaßen einbinden:
<iframe src="./script.php?url=http://example.com"></iframe>

Vielen Dank schon mal für die schnelle Antwort!
Also ich habs versucht aber jetzt wird kein Inhalt angezeigt...die Seite ist einfach weis.

Folgende Seite möchte ich zum Beispiel auf meiner Homepage einbetten

http://www.mystatsonline.com/hockey/visitor/league/standings/standings_hockey.aspx?IDLeague=6826

und das hier ist meine Seite:

http://gladiatoreishockey.lima-city.de/test/

Ich nutze Wordpress, daher habe ich die script.php
mit Inhalt:
<?php
$url = isset($_GET['url']) ? $_GET['url'] : '';
if($url)
{
    $header = get_headers($url, true);
    header('Content-type: ' . $header['Content-Type']);
    echo file_get_contents($url);
}

auf einem anderen webspace hochgeladen:

https://gladiatoreishockey.lima-city.at/script.php

Hier wird mir allerdings auch schon kein Content angezeigt oder Sourcecode...
Was könnte da jetzt noch das Problem sein?

<iframe src="https://gladiatoreishockey.lima-city.at/script.php?url=http://www.mystatsonline.com/hockey/visitor/league/standings/standings_hockey.aspx?IDLeague=6826"></iframe>

das ist dann der iframe den ich bei meiner Seite:

http://gladiatoreishockey.lima-city.de/test/

angegeben habe.
Hier nochmal die Seite mit der script.php...da ist gerade wohl irgend etwas schief gelaufen..
https://gladiatoreishockey.lima-city.at/script.php

irgendwas stimmt wohl nicht wenn man links posten will..bei mir werden in jedem beitrag den ich hier poste immer die gleichen angezeigt :(

Ich habe deine Kommentare mal zu einem zusammengefasst.

Das Problem habe ich mittlerweile auch erkannt.
Das Script funktioniert nur mit Bildern, wenn du es für ein IFrame benutzen möchtest wird das ganze etwas komplizierter. Ich habe dafür mal was geschrieben und den Blog Artikel angepasst.

Die Kommentar Funktion hier habe ich auch repariert und bei der Gelegenheit gleich noch Code highlighting eingebaut :D

Vielen Dank für alles :)
Das mit dem Code highlighting schaut schon viel besser aus!
Ich habe das Gefühl, ich komme bei mir auch langsam dem Ziel etwas näher...
Habe jetzt eine Fehlermeldung auf meiner Test-Seite:
"Der Server kann diese Webseite nicht laden, da ein Fehler in einem PHP-Skript oder in einer .htaccess-Datei aufgetreten ist."
Jetzt mach ich mich mal schlau, was diese htaccess-Datei überhaupt ist...hab schon öfters davon gelesen..scheint wohl was wichtiges zu sein.
Ah ich habe übrigens auch eines deiner Plugins installiert..das mit dem Icon bei Links fand ich ganz lustig. Aber das klappt nur in meinem Wordpress-Menü bisher.
https://gladiatoreishockey.lima-city.de/2016/11/03/movember-2016/
Auf dieser Seite habe ich Links nach außen. Das Icon meiner Homepage wird aber nicht angezeigt. :(
Grüßle

Über die ".htaccess", beginnt mit einem Punkt was unter Unix/Linux bedeutet, dass die Datei versteckt ist, kannst du die Konfiguration des Webservers teilweise ändern. So kann man für einzelne VHosts/Webseiten unterschiedliche Webserver Konfigurationen verwenden ohne das man die Hauptkonfiguration des Webservers ändern muss. Siehe dazu https://tas2580.net/blog/webseite-htaccess-optimieren.html

Hinter den Links wird doch ein Icon angezeigt, das Icon ändert sich nur nicht da das Plugin die Seiten die du verlinkt hast nicht kennt. Verlinke mal eine Domain die in der Pluginbeschreibung aufgelistet ist. Wenn du weitere Seiten hinzufügen möchtest siehe FAQ des Plugins.

Hallo , soweit so gut, das ich HTTP nicht in HTTPS aufrufen kann habe ich auch schon gemerkt. Deine Erklärung ist wunderschön und würde ich auch nutzen, leider komme ich nicht damit klar was ich jetzt von der Webseite HTTP welche ich per iframe in HTTPS einbinden möchte wo eintragen muss oder sollte. Z.B. wenn dort steht 'url' muss ich dort die URL der Seite eintragen welche ich nun im frame nutzen möchte? vielen Dank

Hallo,

Ich versuche zur Zeit eine http seite in eine https seite mittels iframe einzubinden doch leider funktioniert das nicht :/
Heute bin ich dann mal beim suchen auf diesen beitrag gestoßen und hab mir gedacht das Probierst du einfach mal :D

Ich habe als das für eine Komplette Seite einbinden php script kopiert und damit eine livetest.php erstellt und sie dann auf meinem Webspace hochgeladen.

Als nächstest habe ich dann meinen iframe Code wie folgt umgeändert: (Änderungen sind Fett gedruckt)
<iframe width="100%" height="1000" style="border-style: outset; border-width: 5px; border-color: gold;"  src="./livetest.php?url=http://f1-dtm-liga.com:50041/lapstat"</iframe>


Leider funktioniert das dennoch nicht es wird mir nur der Ramen angezeigt und das wars :/

Hier ginge es zu meiner Seite wo ich den iframe gerne einbinden würde: https://auswertungstool.f1-dtm-liga.com/?page=Liveview

Mach ich da noch was falsch ?

Lg Stefan

Das Zertifikat der Seite die du einbinden möchtest ist ungültig.

Ok ich habe nachgeschaut und gesehen dass das Zertifikat nur für die Haupt Domain gültig ist mein fehler. Ich habe das Zertifikat von der Subdomain nun entfernt und unter http funktioniert es ohne Probleme.

Aber ich habe das gleiche nun über die Haupt Domain (https://f1-dtm-liga.com/) nocheinmal Probiert aber leider nur das Selbe ergebnis man kann entweder nur den Rahmen sehen oder eine fehlermeldung das die seite nicht geldaen werden konnte :/

Hier die Seite wo ich den iframe versucht habe einzubetten:
https://f1-dtm-liga.com/cms/index.php?page/fdl/true/uedh/acmdlhl/

Hier der Code den ich jetzt verwendet habe:
<iframe width="100%" height="1000" style="border-style: outset; border-width: 5px; border-color: gold;"  src="./livetest.php?url=http://f1-dtm-liga.com:50041/lapstat"></iframe>


Ist das noch ein Spezieller fehler von mir im Code oder so ?
Ich habe sicherheitshalber auch nocheinmal den php Code kopiert und neu eingefügt aber keine besserung :/

Lg Stefan

Oder muss ich eventuell noch was in der php datei ändern oder anpassen oder passt es das ich den Code 1 zu 1 übernommen habe ?

Lg Stefan

Das ist sehr hilfreich!!

Ich arbeite mit Wordpress und nun bekomme ich die Seite, welche ich einbinden möchte, in der Vorschau angezeigt.

Aber auf der Liveseite bekomme ich nur die Fehlerseite mit dem Code 404 angezeigt. Woran könnte das liegen?

Vermutlich hast du irgendwo eine relative URL angegeben.

Hallo,
funktioniert der Script auch mit Portweiterleitungen der http Seiten?

Bsp: http://xyz.de:8080

Danke!


Bitte warten ...

Kommentar schreiben

URLs werden automatisch umgewandelt.
[b]DEIN TEXT[/b] für Fett gedruckt
[quote]DEIN ZITAT[/quote] für Zitate
[code]DEIN CODE[/code] für Code
captcha