localStorage and 'file:' protocol not persistent, SQLite gives SECURITY_ERR

余生长醉 提交于 2019-12-17 20:53:23

问题


Introduction

I work with RapidWeaver — Mac OS X CMS application — and it uses no server environment. It has an editor and a preview mode. The preview mode is a Webkit based renderer, and I can use 'Inspect Element', like you normally could do in Safari.

I want to store some settings for a toolbar, either using localStorage or SQLite. I have read some information about indexedDB, though I have found no concrete implementations on how to use it.

Problems with localStorage

localStorage works fine when I stay in the preview mode, when I switch between editor and preview mode the url — location.href — is slightly altered:

file:///private/var/folders/s7/x8y2s0sd27z6kdt2jjdw7c_c0000gn/T/TemporaryItems/RapidWeaver/98970/document-143873968-28/RWDocumentPagePreview/code/styled/index.html

file:///private/var/folders/s7/x8y2s0sd27z6kdt2jjdw7c_c0000gn/T/TemporaryItems/RapidWeaver/98970/document-143873968-29/RWDocumentPagePreview/code/styled/index.html

document-143873968-28 changes into document-143873968-29

What I have read about localStorage, that it's basically globalStorage[location.hostname] for FireFox. As far as I know globalStorage is not supported in Safari, so I can't try that.

Problems with SQLite

When I try to open a database:

var shortName = 'mydatabase';
var version = '1.0';
var displayName = 'My Important Database';
var maxSize = 65536; // in bytes
var db = openDatabase(shortName, version, displayName, maxSize);

I get this in my console:

SECURITY_ERR: DOM Exception 18: An attempt was made to break through the security policy of the user agent.

That basically wraps up my question, I will appreciate any answers or comments sincerely.


回答1:


Using the following solution: Implementing a WebView database quota delegate with a few modifications I was able to get it to work.

The following delegate method worked for me (place in your webViewDelegate):

- (void)webView:(WebView *)sender frame:(WebFrame *)frame exceededDatabaseQuotaForSecurityOrigin:(id) origin database:(NSString *)databaseIdentifier
{
  static const unsigned long long defaultQuota = 5 * 1024 * 1024;
  if ([origin respondsToSelector: @selector(setQuota:)]) {
    [origin performSelector:@selector(setQuota:) withObject:[NSNumber numberWithLongLong: defaultQuota]];
  } else { 
    NSLog(@"could not increase quota for %@", defaultQuota); 
  }
}

By default the database is given 0 bytes, which results in the vague error message you get above. The above method is called after an attempt is made to create a database when there is not enough space. Note that this method is defined in WebUIDelegatePrivate.h ( http://opensource.apple.com/source/WebKit/WebKit-7533.16/mac/WebView/WebUIDelegatePrivate.h ) and using may preclude you from submitting your app to the mac app store.




回答2:


localStorage is a html5 mechanism to give scripts a bit more space than cookies. Safari supports it: https://developer.apple.com/library/archive/documentation/iPhone/Conceptual/SafariJSDatabaseGuide/Name-ValueStorage/Name-ValueStorage.html

I don't know offhand what, if any, path restrictions it should have for file:/// based apps.

Edit: looking into the path restrictions further, I see that what you got should work with Safari, FF recently fixed a bug that would keep it from working there: https://bugzilla.mozilla.org/show%5Fbug.cgi?id=507361



来源:https://stackoverflow.com/questions/7540904/localstorage-and-file-protocol-not-persistent-sqlite-gives-security-err

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!