7

Szukam sposobu na wyświetlenie izolowanej nakładki na niektórych stronach internetowych przy użyciu rozszerzenia WebExtensions.
Iframe wydaje się być sposobem na to, ponieważ zapewnia oddzielny zakres dla css, js i DOM. Kolejną fajną rzeczą jest to, że docelowa strona nie będzie mogła odczytać ani zmienić treści.Internetowe rozszerzenie przeglądarki Firefox, izolowana nakładka HTML

W rozszerzeniach Chrome, które wydają się możliwe bez żadnych problemów, ale z rozszerzeniami Web w Firefoksie, mimo że mają tę samą składnię, otrzymuję ostrzeżenia/błędy bezpieczeństwa i to nie działa.

Próbowałem dwóch różnych rzeczy:

  • tworzenia iframe bez atrybutu src i wstrzyknąć do organizmu, że strony internetowej. Ta metoda nie powiodła się, ponieważ dostaję błędy/ostrzeżenia CSP, gdy wykonuję iframe.contentWindow.document.open().
    odpowiedni kod treści skryptu:

    let html = ` 
        <!DOCTYPE html> 
        <html> 
         <head></head> 
         <body> 
         <h1>TEST</h1> 
         </body> 
        </html> 
    ` 
    let iframe = document.createElement('iframe') 
    document.body.appendChild(iframe) 
    iframe.contentWindow.document.open() 
    iframe.contentWindow.document.write(html) 
    iframe.contentWindow.document.close() 
    
  • Inną rzeczą próbowałem (co byłoby zrobić więcej sensu gdyż uniemożliwi internetową z dostępem do treści), było umieścić moje kod iframe do pliku (overlay.html) w moim rozszerzeniu internetowym i spraw, aby element iframe wczytał go, ustawiając go jako src na browser.extension.getURL('overlay.html').
    odpowiedni kod treści skryptu:

    let iframe = document.createElement('iframe') 
    iframe.src = browser.extension.getURL('overlay.html') 
    document.body.appendChild(iframe) 
    

    W manifeście ja zdefiniował overlay.html jak web_accessible_resources dla tego:

    "web_accessible_resources": [ 
        "overlay.html" 
    ], 
    

    Chodzi o to, że po prostu nie iframe załadować plik overlay.html. Ale jest zdecydowanie dostępny, w przeciwnym razie location.href = browser.extension.getURL('overlay.html') nie działa. Byłoby niezwykle wygodne, gdyby to działało, ponieważ mogłem przechowywać całą nakładkę (html, css, js) jako osobne pliki w moim rozszerzeniu. Jakby była to samodzielna strona internetowa. I używając skryptu treści, do którego mogłem uzyskać dostęp, aby dodać nowe dane lub cokolwiek innego.

Edit:

Obecnie używam atrybut moim iframe, aby ustawić kod źródłowy powinien zawierać (dzięki wOxxOm do tego) srcdoc. Tak przynajmniej mam coś, co działa teraz. Ale nie podoba mi się to podejście, ponieważ nie mogę wchodzić w interakcję z treścią iframe z mojego skryptu treści. Interesujące jest jednak to, że mogę wchodzić w interakcję ze stroną nadrzędną z kodu js iframe, ale znowu nie ze skryptem treści. Jest również bardzo niechlujny, niewygodny i trudny do utrzymania, aby umieścić cały kod HTML, CSS, JS w jednym ciągu zamiast wielu plików, takich jak zwykła strona internetowa.

+2

Może witryn próbowałem zdefiniować bardzo restrykcyjnej CSP? Spróbowałbym 'iframe.srcdoc'. Jeśli chodzi o izolację stylu, możesz użyć Shadow DOM zamiast iframe. – wOxxOm

+0

Dziękuję, że było to niezwykle pomocne! – Forivin

+0

1) O problemie CSP: Nie sądzę, że to strona. Daje mi ten sam błąd w pliku 'file: /// C: /'. Myślę, że jest to związane z własnym CSP rozszerzenia. Wciąż nie znam składni, więc nie mogę zaoferować rozwiązania. Bądź ostrożny wywiercając dziury bez pełnego zrozumienia, na co jeszcze możesz pozwolić przypadkowo. 2) Stworzyłem natychmiast dołączony element iframe. Bezpośrednie przypisanie NIE działa równo dla wszystkich atrybutów, chociaż "iframe.src" działało dla mnie. Spróbuj podać WSZYSTKIE atrybuty za pomocą 'iframe.setAttribute (attribute, value);' W szczególności myślę, że 'klasa' jest problematyczna. – user314159

Odpowiedz

3

problem

Po pierwsze, wiemy, że problem jest występowanie problemu dotyczącego zabezpieczeń, co dokładnie jest problem? Cóż, próbując wczytać zasób rozszerzenia do elementu iframe, ustawiając element iframe src, przeglądarka uskarża się na zabezpieczenia i zapobiega łączeniu się elementu iframe za pośrednictwem innego protokołu, w tym przypadku "moz-extension: //".

Rozwiązanie

obciążenia etc HTML kontekście rozszerzenia i wstrzyknąć jako ciąg znaków.

Nitty Gritty

Aby obejść ten problem, możemy ustawić atrybut src iframe do data:text/html;charset=utf8,${markup}.

To bezpośrednio informuje iframe, że treść jest html, używa kodowania utf8, a następnie jest surowy znaczników. Całkowicie pomijamy potrzebę ładowania elementów iframe przez sieć.

Kontekst wykonania skryptu treści Firefox jest oddzielony od strony, dla której został załadowany. Oznacza to, że możesz wysłać żądanie xhr bez naruszania CSP.

Po wysłaniu żądania xhr do znaczników można uzyskać treść odpowiedzi jako ciąg znaków i bezpośrednio wprowadzić ją do atrybutu src iframe.

Zatem treść skryptu:

function loaded (evt) { 
    if (this.readyState === 4 && this.status === 200) { 
     var html = this.responseText; 
     console.log(html); 
     var iframe = document.createElement('iframe'); 

     iframe.src = 'data:text/html;charset=utf-8,' + html; 
     document.body.appendChild(iframe); 

     console.log('iframe.contentWindow =', iframe.contentWindow); 
    } else { 
     console.log('problem loading'); 
    } 
} 

var xhr = new XMLHttpRequest(); 
xhr.overrideMimeType("text/html"); 
xhr.open("GET", browser.extension.getURL('test.html'), false); 
xhr.addEventListener("readystatechange", loaded); 


xhr.send(null); 

Z prostego pliku HTML

<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
    <title>Test</title> 
    <meta charset="utf8" /> 
</head> 
<body> 
    <h1>Hello World</h1> 
</body> 
</html> 

Więc teraz z powodzeniem wstrzykiwano szablon HTML do iframe docelowej.

Jeśli potrzebujesz obrazów, skryptów, plików CSS itp., Musisz napisać bootloader w oparciu o metodę opisaną powyżej, wstrzykując nowe znaczniki skryptów i tak dalej bezpośrednio do dokumentu iframe.

0

okazji, czasami używają IFRAME URL w inny protokół, to znaczy
https:// (gdy bieżąca strona http://).

Więc IFRAME url powinny być względne, jak src="//example.com"

+0

Z kontekstu rozszerzenia firefox uzyskującego dostęp do plików z systemu plików rozszerzeń, a nie z kontekstu witryny, to nie zadziała. Pliki rozszerzenia firefox znajdują się w protokole rozszerzenia moz. –

Powiązane problemy