How to load local CSS in a remote web page in WKWebView?

950 Views Asked by At

Updated question

I am loading a remote page that I control into a WKWebview in my app and customizing it by loading local CSS and font files. At page load, in webView:didFinishNavigation:, I am running some JS to inject some style tags and a link element whose src points to a local file via a custom URL scheme myfile implemented via WKURLSchemeHandler. The local file is being blocked from loading by what appears to be Content Security Policy.

I am not able to add headers because the page I'm loading is in an S3 bucket, but I have added a meta tag to the head on the server (not injected with JS):

<meta http-equiv="Content-Security-Policy" content="default-src 'self' otfile:; style-src 'self' 'unsafe-inline' 'unsafe-eval' http: https: data: otfile:"/>

Even with this addition, the web view does not attempt to load the local CSS - looking at the Safari web inspector, the link element is in the head but the CSS file doesn't show up on the network tab. Evaluating await fetch('otfile://myfile.css') in the console produces a warning like this:

[blocked] The page at https://my-bucket.s3.amazonaws.com/file.xhtml was not allowed to display insecure content from otfile://file.css.

An example project demonstrating the issue can be found here.

My question has now become: How do I specify to WKWebView / WebKit that it's permitted to load arbitrary content via my custom URL scheme here?


See below for original

I'm loading a remote page in a WKWebView, and I need to customize the styling of it by injecting a reference to a local CSS file at page load using Javascript. I'm using an implementation of WKURLSchemeHandler to do this. When I set up my web view:

WKFileLoadHandler *fileHandler = [[MyFileLoadHandler alloc]init];
[config setURLSchemeHandler:fileHandler forURLScheme:@"myfile"];

self.webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:config];
self.webView.navigationDelegate = self;
self.webView.allowsLinkPreview = NO;
self.webView.opaque = NO;
[self.view addSubview:self.webView];
[self.webView autoPinEdgesToSuperviewEdges];

//self.url is a remote url
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:self.url];
request.cachePolicy = NSURLRequestReloadIgnoringLocalAndRemoteCacheData;
[self.webView loadRequest:request];

Then, when the page has loaded, in webView:didFinishNavigation:

NSMutableString *strJs = [NSMutableString string];
[strJs appendString:@"var cssTag = document.createElement('link');\n"];
[strJs appendString:@"cssTag.setAttribute('type', 'text/css');\n"];
[strJs appendString:@"cssTag.setAttribute('href', 'myfile://bundle/css/engine.css');\n"];
[strJs appendString:@"cssTag.setAttribute('rel', 'stylesheet');\n"];
[strJs appendString:@"document.head.appendChild(cssTag);\n"];
[self.webView evaluateJavascript:strJs completionHandler:nil];

In my code I have a completion handler that I've omitted here for brevity, and there is no error reported when running the JS.

What I'm seeing is that the web view does not attempt to load the CSS file. It never even makes a call to the scheme handler, and it doesn't show up in the Web Inspector as a request that was attempted.

I have tried setting the href of the link element to a remote URL instead, and the web view attempts to load that. I also tried creating an img element with its src set to a myfile:// URL and appending it to the document body, and the web view attempts to load that.

Is there a property or security policy or something that prevents WKWebView from loading CSS documents using custom scheme handlers when the document it has open is via https?

Update: this appears to be the same issue as this question.

0

There are 0 best solutions below