Alternatywa dla iFrames z HTML5

196

Chciałbym wiedzieć, czy istnieje alternatywa dla iFrames z HTML5. Rozumiem przez to możliwość wstrzykiwania kodu HTML między domenami na stronie internetowej bez użycia ramki iFrame.

stemlaur
źródło

Odpowiedzi:

96

Zasadniczo istnieją 4 sposoby osadzenia HTML na stronie internetowej:

  • <iframe>Treść iframe żyje całkowicie w innym kontekście niż strona. Chociaż jest to w większości świetna funkcja i najbardziej kompatybilna z wersjami przeglądarki, stwarza dodatkowe wyzwania (zmniejszanie rozmiaru ramki do jej zawartości jest trudne, szalenie frustrujące przy włączaniu i wyłączaniu skryptów, prawie niemożliwe do stylu).
  • AJAX . Jak pokazują przedstawione tutaj rozwiązania, możesz użyć XMLHttpRequestobiektu do pobrania danych i wstrzyknięcia ich na twoją stronę. Nie jest idealny, ponieważ zależy od technik skryptowych, co powoduje, że wykonywanie jest wolniejsze i bardziej złożone, między innymi wadami .
  • Hacki . Nieliczni wspomniani w tym pytaniu i niezbyt wiarygodni.
  • Składniki sieciowe HTML5 . Import HTML, będący częścią Web Components, pozwala na wiązanie dokumentów HTML w inne dokumenty HTML. Która obejmuje HTML, CSS, JavaScriptlub cokolwiek innego .htmlplik może zawierać. To sprawia, że ​​jest to świetne rozwiązanie z wieloma interesującymi przypadkami użycia: podziel aplikację na pakiety, które możesz dystrybuować jako bloki konstrukcyjne, lepiej zarządzaj zależnościami, aby uniknąć redundancji, organizacji kodu itp. Oto prosty przykład:

    <!-- Resources on other origins must be CORS-enabled. -->
    <link rel="import" href="http://example.com/elements.html">
    

Natywna kompatybilność wciąż stanowi problem, ale możesz użyć wielowypełniacza, aby działał w wiecznie zielonych przeglądarkach .

Możesz dowiedzieć się więcej tutaj i tutaj .

Oriol
źródło
3
Składniki sieciowe HTML5 są interesujące.
Krishna Srihari
1
Wiem, że ten post jest trochę stary, ale chcę to skomentować: W odniesieniu do AJAX: „To nie jest pomysł, ponieważ opiera się na technikach skryptowych” ... Więc co jest nie tak z używaniem skryptów? AJAX jest niekwestionowanym liderem wśród tych wyborów i szybko staje się standardem.
nmg49
11
Niestety importowanie HTML jest teraz przestarzałą funkcją. developer.mozilla.org/en-US/docs/Web/Web_Components/…
Gman
Jakiś nowy sposób na osiągnięcie tego?
Walter
Kolejną istotną wadą iFrames jest fakt, że istnieje wiele stron internetowych, które ustawiły „X-Frame-Options” na „sameorigin”, a następnie po prostu odmówiły połączenia. W takim przypadku ramka iFrame pozostaje pusta. Nie ma sposobu, aby to naprawić.
Igor P.
61

Możesz użyć obiektu i osadzić, tak jak:

<object data="http://www.web-source.net" width="600" height="400">
    <embed src="http://www.web-source.net" width="600" height="400"> </embed>
    Error: Embedded data could not be displayed.
</object>

Co nie jest nowe, ale nadal działa. Nie jestem jednak pewien, czy ma taką samą funkcjonalność.

Nate
źródło
Dzięki stosy, uratowałem mnie ładowanie sdk dla facebooków takich jak box.
Witryna techniczna
51

Nie, nie ma odpowiednika. Ten <iframe>element jest nadal aktualny w HTML5. W zależności od potrzebnej dokładnej interakcji mogą istnieć różne interfejsy API. Na przykład istnieje postMessagemetoda, która pozwala uzyskać interakcję javascript między domenami. Ale jeśli chcesz wyświetlać zawartość HTML między domenami (stylizowana za pomocą CSS i interaktywna z javascript), iframepozostaje dobrym sposobem.

Darin Dimitrov
źródło
3
Muszę załadować treść z Google. ale Google nie może być zepsuty, jaka jest alternatywa.
Mike
17
@Mike, alternatywą byłoby użycie interfejsu API dla usługi, z której chcesz korzystać. Google zapewnia interfejsy API RESTful dla większości swoich usług.
Darin Dimitrov
45

object jest łatwą alternatywą w HTML5:

<object data="https://blogs.claritycon.com/blog/2016/03/bower-packages-asp-net-core-1-0/" width="400" height="300" type="text/html">
    Alternative Content
</object>

Możesz także spróbować embed:

<embed src="https://blogs.claritycon.com/blog/2016/03/bower-packages-asp-net-core-1-0/" width=200 height=200 onerror="alert('URL invalid !!');" />

Abrar Jahin
źródło
4
oba nie omijają problemów, które mam z
elementami
3
Należy pamiętać, że większość współczesnych przeglądarek ma przestarzałą i usuniętą obsługę wtyczek do przeglądarek, więc poleganie na <embed> nie jest ogólnie rozsądne, jeśli chcesz, aby Twoja witryna działała w przeglądarce przeciętnego użytkownika.
Neeraj
20

Jeśli chcesz to zrobić i kontrolować serwer, z którego obsługiwana jest strona podstawowa lub treść, możesz skorzystać z udostępniania zasobów pochodzących z wielu źródeł ( http://www.w3.org/TR/access-control/ ), aby umożliwić klientowi bok JavaScript danych ładowania do <div>urządzeń XMLHttpRequest():

// I safely ignore IE 6 and 5 (!) users
// because I do not wish to proliferate
// broken software that will hurt other
// users of the internet, which is what
// you're doing when you write anything
// for old version of IE (5/6)
xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
  if(xhr.readyState == 4 && xhr.status == 200) {
    document.getElementById('displayDiv').innerHTML = xhr.responseText;
  }
};
xhr.open('GET', 'http://api.google.com/thing?request=data', true);
xhr.send();

Teraz, dla linczu tej całej operacji, musisz napisać kod dla swojego serwera, który da klientom Access-Control-Allow-Originnagłówek, określając, do których domen chcesz uzyskać dostęp po stronie klienta XMLHttpRequest(). Poniżej znajduje się przykład kodu PHP, który możesz umieścić na górze strony, aby wysłać te nagłówki do klientów:

<?php
  header('Access-Control-Allow-Origin: http://api.google.com');
  header('Access-Control-Allow-Origin: http://some.example.com');
?>
L0j1k
źródło
8

Ramka iframe jest nadal najlepszym sposobem pobierania treści wizualnych między domenami. Z AJAX z pewnością możesz pobrać HTML ze strony internetowej i umieścić go w div (jak wspomnieli inni), jednak większym problemem jest bezpieczeństwo. Dzięki ramkom iframe będziesz mógł załadować zawartość między domenami, ale nie będziesz mógł nią manipulować, ponieważ zawartość nie należy do Ciebie. Z drugiej strony za pomocą AJAX z pewnością możesz manipulować dowolną zawartością, którą możesz pobrać, ale serwer drugiej domeny musi być skonfigurowany w taki sposób, abyś mógł rozpocząć pobieranie. Wiele razy nie będziesz mieć dostępu do konfiguracji innej domeny, a nawet jeśli to zrobisz, chyba że robisz taką konfigurację przez cały czas, może to być ból głowy. W takim przypadku element iframe może być DUŻO łatwiejszą alternatywą.

Jak wspomnieli inni, możesz także użyć znacznika embed i tagu obiektu, ale niekoniecznie jest to bardziej zaawansowane lub nowsze niż iframe.

HTML5 poszedł bardziej w kierunku przyjmowania internetowych interfejsów API w celu uzyskiwania informacji z różnych domen. Zwykle internetowe interfejsy API tylko zwracają dane, a nie HTML.

Adam
źródło
1
To nie jest tak naprawdę odpowiedź, ale na pewnonice-to-know
Stef Geysels
4

Możesz użyć XMLHttpRequest, aby załadować stronę do div (lub dowolnego innego elementu strony). Przykładową funkcją byłoby:

function loadPage(){
if (window.XMLHttpRequest){
    // code for IE7+, Firefox, Chrome, Opera, Safari
    xmlhttp=new XMLHttpRequest();
}else{
    // code for IE6, IE5
    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}

xmlhttp.onreadystatechange=function(){
    if (xmlhttp.readyState==4 && xmlhttp.status==200){
        document.getElementById("ID OF ELEMENT YOU WANT TO LOAD PAGE IN").innerHTML=xmlhttp.responseText;
    }
}

xmlhttp.open("POST","WEBPAGE YOU WANT TO LOAD",true);
xmlhttp.send();
}

Jeśli twój serwer jest w stanie, możesz również użyć PHP, ale ponieważ prosisz o metodę HTML5, to powinno ci wystarczyć.

CupOfTea696
źródło
4
Ładowanie zawartości z innych domen za pomocą XMLHttpRequest jest blokowane przez większość przeglądarek.
Erik Terenius
4
Op prosi o podanie wielu domen, ta odpowiedź jest nieprawidłowa.
Teoman shipahi
4

Utworzyłem moduł węzła, aby rozwiązać ten problem zamiany węzła iframe . Podajesz źródłowy adres URL witryny nadrzędnej i selektor CSS, do którego chcesz wstrzyknąć treść, i łączy je ze sobą.

Zmiany w witrynie nadrzędnej są rejestrowane co 5 minut.

var iframeReplacement = require('node-iframe-replacement');

// add iframe replacement to express as middleware (adds res.merge method) 
app.use(iframeReplacement);

// create a regular express route 
app.get('/', function(req, res){

    // respond to this request with our fake-news content embedded within the BBC News home page 
    res.merge('fake-news', {
        // external url to fetch 
       sourceUrl: 'http://www.bbc.co.uk/news',
       // css selector to inject our content into 
       sourcePlaceholder: 'div[data-entityid="container-top-stories#1"]',
       // pass a function here to intercept the source html prior to merging 
       transform: null
    });
});

Źródło zawiera działający przykład wstrzykiwania treści na stronę główną Wiadomości BBC .

John Doherty
źródło
0

Powinieneś rzucić okiem na JSON-P - było to dla mnie idealne rozwiązanie, gdy miałem ten problem:

https://en.wikipedia.org/wiki/JSONP

Zasadniczo definiujesz plik javascript, który ładuje wszystkie dane, oraz inny plik javascript, który go przetwarza i wyświetla. Pozbywa się brzydkiego paska przewijania iframe.

Mathias Bader
źródło