17

I've got an Android webview, that I believe has everything required to access and use localStorage, however, I'm seeing an "Access denied" error in the console when trying to use local storage. Uncaught SecurityError: Failed to read the 'localStorage' property from 'Window': Access is denied for this document.

Can anyone spot a problem?

JavaScript Code:

function localStorageTest() {
  // Check browser support
  if (typeof(Storage) != "undefined") {
    // Store
    localStorage.setItem("lastname", "Smith");
    // Retrieve
    document.getElementById("console").innerHTML = localStorage.getItem("lastname");
  } else {
    document.getElementById("console").innerHTML = "Sorry, your browser does not support Web Storage...";
  }
}

Here's the Android code:

    // Enable javascript
    WebSettings settings = getSettings();
    settings.setJavaScriptEnabled(true);
    settings.setDomStorageEnabled(true);
    settings.setDatabaseEnabled(true);

    // Create database folder
    String databasePath = getContext().getDir("databases", Context.MODE_PRIVATE).getPath();
    getSettings().setDatabasePath(databasePath);

    getContext().getPackageName() + "/databases/");

    settings.setAppCacheEnabled(true);
    settings.setSaveFormData(true);;
    settings.setLoadWithOverviewMode(true);
    settings.setSaveFormData(true);
bugfixr
  • 7,997
  • 18
  • 91
  • 144

6 Answers6

17

Access to localStorage is only allowed on pages from certain "Web-safe" schemes, like http:, https: and file:. It doesn't work for about: and data: schemes for example, or for any custom scheme you might be using. Chrome behaves the same way, you can check on desktop.

Mikhail Naganov
  • 6,643
  • 1
  • 26
  • 26
  • Hmm... so if I just load my own HTML content instead of serving it from a server, it won't work? – bugfixr May 05 '15 at 21:43
  • 3
    Try using `WebView.loadDataWithBaseUrl` and specify a base URL starting with `http:` scheme. Or you can run a simple web server inside your app. – Mikhail Naganov May 05 '15 at 22:59
  • 1
    why is access being denied for me locally in the `file://` protocol then? – oldboy Oct 02 '19 at 01:03
5

To manipulate the global object in JS we need a trick. As @Mikhail Naganov said chromium complains about security Access denied using local storage in Android WebView

I load js as a base url and in js also redirect to the real url. Below code worked for me in android 7

    String mimeType = "text/html";
    String encoding = "utf-8";
    String injection = "<script type='text/javascript'>localStorage.setItem('key', 'val');window.location.replace('REAL_URL_HERE');</script>";
    webview.loadDataWithBaseURL("REAL_URL_HERE", injection, mimeType, encoding, null);
canbax
  • 3,432
  • 1
  • 27
  • 44
  • 1
    I used the same code for ios and WKWebView. It also working there – canbax Apr 06 '18 at 07:59
  • It resolved error `Uncaught SecurityError: Failed to read the 'localStorage' property from 'Window': Storage is disabled inside 'data:' URLs.` in my case. Thanks – kosiara - Bartosz Kosarzycki Aug 01 '18 at 11:14
  • maybe WebView in android changed. I didn't run android for 8 months. @Ryan this line "window.location.replace('REAL_URL_HERE')" should redirect to the URL that you wanted – canbax Feb 01 '19 at 08:27
  • Yeah for some reason it doesn't redirect, or an empty page loads instead. I ended up solving it differently by basically loading the url twice, once before evaluating the script and once again after evaluating the script, not ideal but worked... If someone runs into this I can share solution, just mention me – Ryhan Feb 04 '19 at 19:17
  • Hi @Ryhan, I am facing the same problem. Can you please share your code? – Vivek Jun 18 '21 at 04:37
3

This worked for me

webview.getSettings().setAllowFileAccess(true);
Gil
  • 568
  • 5
  • 9
1

Did you ask for permissions to access storage and network in your manifest.xml ?

Something like this :

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Damien
  • 141
  • 1
  • 6
  • Well... I find people having this issue with google-chrome, but can't find it for just a ViewPager, but who knows, maybe this could help : http://stackoverflow.com/questions/24456891/iframe-in-chrome-error-uncaught-securityerror-failed-to-read-the-sessionstora – Damien May 05 '15 at 21:11
1

I was getting a related error. All was the same except for the final part Access is denied for data:

In my case I was loading an html content that interact with a script with an specify src. In order for the webView to render this src I had to extract the url from the <script> section and call it on the method loadDataWithBaseURL as the baseUrl and put the html as the data.

web.loadDataWithBaseURL(urlSrc, data, "text/html", "utf-8")
Renato
  • 93
  • 3
  • 8
  • 1
    Same for me. I needed to show an embedded TikTok video, with a html string as the content. Using the base url for the TikTok script needed on the embedded video on loaddatawithbaseurl rendered the TikTok videos on the WebView. – Xaren Jul 26 '21 at 22:47
1

Try using below method calls to enable local storage in the webview.

webView.getSettings().setDomStorageEnabled(true);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setDatabaseEnabled(true);
Nilesh
  • 532
  • 7
  • 13