2016-04-15 2 views
2

In meiner ionic (v1.2.4) App gibt es einen eingebetteten Youtube Player mit einem Link "watch on youtube". Wenn ein Nutzer auf diesen Link klickt, wird die Youtube-Website in der Webansicht von Cordova geöffnet. Es zerstört den aktuellen Zustand meiner App. Ich möchte diesen Link im Webbrowser des Systems öffnen (cordova in app browser plugin).Ionic: Externer Link in iframe öffnet sich im Webview (embed youtube player)

Das Gleiche gilt für einen beliebigen Link in jedem iframe (Vimeo, Soundcloud ...)

Dieser Link kann nicht von außerhalb des iframe, da Cross-Domain-Sicherheitsprobleme mit JS geändert werden. Daher kann ich das Zielattribut nicht von _blank auf _system aktualisieren.

zeigen ein Dialog onbeforeunload nicht wirklich eine Option ist, weil es hässlich aussieht :)

Gibt es eine Möglichkeit, eine Seite zu vermeiden, in die gleiche Webansicht oder in dem System Web-Browser geladen wird? Das Brechen von Links mit dem Attribut sandbox von iframe ist keine Option, da es den youtube-Player vollständig unterbricht.

Dank und Jubel

ps: fragte ich diese Frage here konnte aber keine hilfreiche Informationen

Antwort

0

Ok bekommen, ist diese Art von Hardcore-Lösungen für diese und sollte wohl neu geschrieben werden/codiert . Diese Lösung verwendet einen Cordova-Haken und öffnet ALLE Links mit HTTP- oder HTTPS-Protokoll zu einem nativen Webbrowser, wenn sie von einem a-Tag geklickt werden. Zum Beispiel <a href="https://www.youtube.com/embed">. Dies betrifft nicht nur iframes, sondern alle Links.

Seien Sie vorsichtig, da sich dies auf einige unerwünschte Links in Ihrer App auswirken kann.

Ich bin mit

  • Cordova 6.1.1
  • Cordova-ios 4.1.1
  • Cordova-Android 5.1.1

Zunächst müssen Sie eine erstellen Haken Sie den Ordner hooks/after_platform_add ein. Dadurch wird der Haken nur ausgeführt, wenn Sie ionic platform add <platform> oder cordova platform add <platform> verwenden. Wenn Sie keinen Ordner after_platform_add haben, erstellen Sie einfach einen. Erstellen Sie dann eine Datei "01_ios_external_links_hook.js".

Auch bitte lesen Cordova Haken Dokumentation:

https://cordova.apache.org/docs/en/latest/guide/appdev/hooks/

Es gibt mehrere Möglichkeiten, von Haken zu definieren und das Erstellen von Ordnern für sie als veraltet zu sein scheint, so dass Sie die config.xml Haken befestigen verwenden sollten.

https://cordova.apache.org/docs/en/latest/guide/appdev/hooks/index.html#via-hooks-directory-deprecated

Sie können Ihre Datei etwas rufen, und wenn Sie es mit Ordnern nur daran denken, tun Zugriffsrechte auf die Datei hinzuzufügen.Typischerweise Klemme:

chmod +x project/hooks/after_platform_add/01_ios_external_links_hook.js. 

Bitte beachten Sie, dass dieses Update nur für iOS-Geräte gedacht ist auf Android, da Sie <access origin="*" /> dies mit der Einstellung <allow-intent href="http://*/*" /> und Einstellung handhaben können. Aber auf dem neuesten Cordova-ios und Whitelist-Plugin müssen Sie <allow-navigation href="*.youtube.com" /> oder ähnliches setzen, damit der Inhalt von iframe auf iOS geladen werden kann. Dies führt zu einer Situation, die Sie beschrieben haben, nämlich dass externe URLs aus dem Iframe in der Webansicht geöffnet werden.

Aber zurück zur Lösung. Dies ist der Code, den ich in der 01_ios_external_links.js Datei:

#!/usr/bin/env node 

var fs = require('fs'); 
var replace = require('replace'); 

if (fs.existsSync('platforms/ios/CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewDelegate.m')) { 

    console.log('platforms/ios/CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewDelegate.m - FOUND: fixing'); 

    replace({ 
    regex: /.*BOOL shouldLoad = YES;*./g, 
    replacement: 'BOOL shouldLoad = YES; NSURL * requesturl = [request URL]; NSString * url = [[request URL]absoluteString]; NSString * documenturl = [[request mainDocumentURL]absoluteString]; if ((navigationType == UIWebViewNavigationTypeLinkClicked && ([[requesturl scheme] isEqualToString:@"http"] || [[requesturl scheme] isEqualToString:@"https"])) || (([url isEqualToString:documenturl]) && ([[requesturl scheme] isEqualToString:@"http"] || [[requesturl scheme] isEqualToString:@"https"]))) { [[UIApplication sharedApplication] openURL:requesturl]; return NO;}', 
    paths: ['platforms/ios/CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewDelegate.m'], 
    recursive: true, 
    silent: true, 
    }); 

} else { 
    console.log('platforms/ios/CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewDelegate.m - NOT FOUND'); 
} 

Bitte beachten Sie, dass dies eine riskante Operation ist zu tun, aber ich hatte keine andere Möglichkeit, zu der Zeit mit diesem Problem beschäftigen. Der obige Code sucht nach einer Datei mit dem Namen CDVUIWebViewDelegate.m im angegebenen Pfad und versucht dann, dort einen Code zu finden und durch einen anderen Code zu ersetzen. Aber in aller Kürze über den Code wird die Plattform-spezifischen Code für iOS im CDVUIWebViewDelegate ändern und eine hinzufügen, wenn Anweisung der folgenden Art zu dieser Datei:

NSURL * requesturl = [request URL]; 
NSString * url = [[request URL]absoluteString]; // URL that was requested 
NSString * documenturl = [[request mainDocumentURL]absoluteString]; // Main document URL 

if ((navigationType == UIWebViewNavigationTypeLinkClicked && ([[requesturl scheme] isEqualToString:@"http"] || [[requesturl scheme] isEqualToString:@"https"])) || (([url isEqualToString:documenturl]) && ([[requesturl scheme] isEqualToString:@"http"] || [[requesturl scheme] isEqualToString:@"https"]))) { 
    [[UIApplication sharedApplication] openURL:requesturl]; // forward to application router 
    return NO; 
} 

Bedenken Sie, dass ich bin keine Objective-C-Coder und das ist alles neu für mich auch und ich habe diese Lösung gemacht, weil ich keine anderen Lösungen für mein Problem gefunden habe, die funktionierten. Die obige if-Anweisung könnte und sollte an Ihre Bedürfnisse angepasst werden. Ich habe diesen Code nur in der Entwicklungsumgebung verwendet und muss diese Methode weiter untersuchen und verbessern, bevor ich sie in einer Produktionsumgebung implementiere.

Denken Sie daran, dass Sie die Plattform entfernen und hinzufügen müssen, damit dies wirksam wird. Dies tritt nur auf, wenn eine Plattform wie oben angegeben hinzugefügt wird.

Aber das ist es. Jetzt öffnet Ihre iOS-Anwendung alle URLs in einem nativen Browser. Hoffentlich hilft Ihnen das in die richtige Richtung, um eine (bessere?) Lösung für dieses Problem zu finden.

2

Danke Thepio für den Hinweis mit allow-intent und allow-navigation. Das erste Mal habe ich wirklich in gegraben. Schließlich fixierte i auf Android mein Problem, indem sie die richtigen allow Attribute in config.xml Einstellung

<!-- Allow links to web pages to open in a browser --> 
<allow-intent href="http://*/*" /> 
<allow-intent href="https://*/*" /> 

Keine allow-navigation für Android. Perfekte White-Label-Lösung. Konnte nicht herausfinden, wie dies unter iOS funktioniert, da iOS allow-navigation Attribute benötigt, um Iframe-Inhalt überhaupt zu laden.

Um meine Probleme auf iOS in einer schmutzigen Weise zu beheben, habe ich diese zu meinem config.xml:

<platform name="ios"> 
    <allow-navigation href="https://w.soundcloud.com/player/*"/> 
    <allow-navigation href="https://www.youtube.com/embed/*"/> 
    <allow-navigation href="https://player.vimeo.com/video/*"/> 
</platform> 

Jetzt ist nur der iframe Inhalt selbst geladen wird. Lucky me, jeder Link (schau auf YouTube, share, wie auf vimeo ...) innerhalb des iframe zeigt auf eine andere Domain/Subdomain, so dass es auf iOS blockiert ist.

Wenn es irgendwelche Vorschläge gibt, wie eine White Label-Lösung für iOS zu erstellen, bin ich ganz Ohr.

Dank

Verwandte Themen