WKWebView gives SecurityError when bundling html a

2019-06-07 14:55发布

We are trying to migrate a hybrid app from UIWebView (iOS < 8) to WKWebView (iOS 8), but we are getting SecurityErrors when trying to store stuff using the DOM WebDatabase API (i.e. 'web sql databases').

The following throws an error if the index.html has been loaded from a bundled file with the app

// throws SecurityError: DOM Exception 18
var db = openDatabase('mydb', '1.0', 'key value store', 1);

The same code works fine with UIWebView. I can fallback to using Local Storage for some reason, but using WebSQL databases is a no go. I can only speculate that this has something to do with the same origin policy or something related.

The funny thing is that loading index.html from the network works fine :-/

Any clues as to how I can work around this? Any options to set on the WKWebView that fixes it?

This is how we load the web related stuff:

NSString *htmlPath = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];
NSURL *baseURL = [NSURL fileURLWithPath:htmlPath];
NSURLRequest *request = [NSURLRequest requestWithURL:baseURL];

WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
[config.userContentController addScriptMessageHandler:self.myCallbacks name:@"NativeApp"];

self.webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:config];

[self.webView loadRequest:request];

The html file simply loads a javascript file that has a relative path, "myCode.js".

3条回答
爷、活的狠高调
2楼-- · 2019-06-07 15:09

There is an issue (OpenRadar) with WKWebView in iOS 8.0 (and 8.1 B1, I think) that prevents it from loading local files. It might be affecting local storage too. See this question for more details.

查看更多
贼婆χ
3楼-- · 2019-06-07 15:25

You can fix this by adding the following method to the UIDelegate of your WKWebView.

- (void)                        _webView:(WKWebView *)webView
    decideDatabaseQuotaForSecurityOrigin:(WKSecurityOrigin *)securityOrigin
                            currentQuota:(unsigned long long)currentQuota
                      currentOriginUsage:(unsigned long long)currentOriginUsage
                    currentDatabaseUsage:(unsigned long long)currentUsage
                           expectedUsage:(unsigned long long)expectedUsage
                         decisionHandler:(void (^)(unsigned long long newQuota))decisionHandler {
    decisionHandler(1024*1024*50); //default to 50MB
}

It gives all databases a quota of 50MB, instead of the default of 0 which allows them to be opened. This behavior isn't documented, so I don't know where Apple stands with this.

Also, it appears this issue will be fixed in iOS 10.

查看更多
甜甜的少女心
4楼-- · 2019-06-07 15:28

I've made a 'plugin' that allows you to use WebSQL (more an implementation of it) in the WKWebView. It can be found here

https://github.com/ajwhiteway/WKWebSQL

import WKWebSQL
.
.
.
var webView = WKWebView(frame: view.frame, configuration: WKWebViewConfiguration())
WKWebSQL.LoadPlugin(webView)

To get it loaded into the page. Versioning isn't really supported at this time. Feel free to add it.

查看更多
登录 后发表回答