Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iframe content from external source not loading in local HTML file on iOS

I created a local HTML file in my iOS app written in swift. The HTML file is loaded into a WKWebView as follows:

let url = Bundle(identifier: myIdentifier).url(forResource: "localHtmlFile", withExtension: "html")
let htmlFormatString = try String(contentsOf: url)
loadHTMLString(string: htmlFormatString, baseURL: nil)

The HTML page contains an iframe which I expect to load an external page:

<div>Test</div>
<iframe src="https://www.somepage.com"></iframe>

The local HTML file is loaded successfully, as I can see the Test text in the div. The iframe is also created, but empty. If I debug with Safari Developer Tools, there is just an empty html page, but nothing loaded. Also, a network request to the url is not performed at all.

But if I insert an external JavaScript file with <script src="https://url-to-some-js">, the JS code will be loaded successfully, so there are no network issues. Also, if I load the url directly with webView.load(URLRequest(url: url)), it's working fine. Only within an iframe, it's not working.

How can I make iframes to external resources working in iOS WKWebView? Is this blocked by iOS at all or do I have to configure something else?

like image 222
UoS Avatar asked Apr 09 '19 15:04

UoS


People also ask

Why can't I test iframes locally in PHP?

It's because its local using file:// which is not supported you'd need to follow Gronostaj method. Ideally you should never test iframes locally. And to be honest there should be no need to use iframes on same site content just use php include.

Why can't I embed a website as an iframe?

Most probably web site that you try to embed as an iframe doesn't allow to be embedded. You need to update X-Frame-Options on the website that you are trying to embed to allow your Power Apps Portal (if you have control over that website). You can find more here.

How do I load a test file in an iframe?

You can't load local files from your computer through the server. You should upload the test file to your server to and then load this file in an iframe. As you have the page on your server you need to use an http:// url, not file:///. It's a little tricky because the web server has a different syntax for file paths than your file system.

Can I use iframes in the same directory as main page?

You can use these if test.html is in the same directory as your main-page. (The main-page is the html with the iframe in it.) You can use this if test.html is in the parent directory of your main-page, as long as it doesn't go beyond the web server's "root" directory.


2 Answers

Based on some googling, it looks like you need to use the delegate method for the webView to allow external sites. Specifically, implement webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) with the following recommended implementation:

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {

    guard let requestURL = navigationAction.request.url?.absoluteString else { return }

    if requestURL.contains("somepage.com") {
        decisionHandler(.allow)
    }
    else {
        // You don't need to cancel here, but you can implement your own logic here
        decisionHandler(.cancel)
    }
}
like image 146
binaryPilot84 Avatar answered Oct 09 '22 20:10

binaryPilot84


Doing this on desktop browsers, where you have a local HTML file and a remote iFrame causes some security issues, so I expect you're hitting the same problem here.

Can you move your local content to a remote server? It doesn't have to be the same as your iframe content, although that will make your life easier.

If you have a lot of local data, then you could send a POST request for the parent page containing a JSON object of your local data.

like image 38
David Bradshaw Avatar answered Oct 09 '22 21:10

David Bradshaw