Zeronet: How to use localStorage?

Created on 22 Apr 2018  路  53Comments  路  Source: HelloZeroNet/ZeroNet

I need to connect localStorage to remember the user's actions.
But I get an error
Uncaught DOMException: Failed to read the 'localStorage' property from 'Window': The document is sandboxed and lacks the 'allow-same-origin' flag.
We can bypass or add allow-same-origin?

Most helpful comment

Thanks to all
very helped next I myself

All 53 comments

Can I ask for help, maybe I'm wrong.
A code that changes the style of the site and remembers the user's actions.

'use strict';
// create <link rel="stylesheet" href="light|dark.css">
let head = document.head,
    link = document.createElement('link');
link.rel = 'stylesheet';
// check the value from localStorage
if (localStorage.getItem('themeStyle') === 'dark') {
  link.href = 'css/dark.css'; // link to a dark style
  document.getElementById('switch-1').setAttribute('checked', true); // switch the checkbox to the "dark theme"
}
// default light theme
else {
  link.href = 'css/light.css'; // link to light style
}
head.appendChild(link); // insert the <link rel="stylesheet" href="light|dark.css"> into the header of the page between the head

// event when switching checkbox
document.getElementById('switch-1').addEventListener('change', ev => {
  let btn = ev.target;
  // if the checkbox is enabled
  if (btn.checked) {
    link.href = 'css/dark.css'; // turn off the dark theme
    localStorage.setItem('themeStyle', 'dark'); // write the value in localStorage
  }
  else {
    link.href = 'css/light.css'; // turn on the light theme
    localStorage.setItem('themeStyle', 'light'); // write the value in localStorage
  }
});

  <div class="switch">
    <input type="checkbox" id="switch-1" class="switch-check">
    <label for="switch-1" class="switch-label">
        袨锌褑懈褟
        <span class="switch-slider switch-slider-on"></span>
        <span class="switch-slider switch-slider-off"></span>
    </label>
  </div>

  <script type="text/javascript" src="js/script.js?=version=1.0" charset="UTF-8"></script>

How do I properly use the API?

I keep a copy of localStorage in a JS object:

var local_storage = {} ;
ZeroFrame.cmd("wrapperGetLocalStorage", [], function (res) {
var key ;
for (key in local_storage) if (!res.hasOwnProperty(key)) delete local_storage[key] ;
for (key in res) local_storage[key] = res[key] ;
}) ;

update local_storage as a normal object

save to ZeroFrame:
ZeroFrame.cmd("wrapperSetLocalStorage", [local_storage], function () {}) ;

the first error was gone, but there was another
Uncaught TypeError: ZeroFrame.cmd is not a function

There is no such file, but I can create.
Is it necessary?

@DATSEC Yup, it's necessary.

I'm trying to use ZeroUP as a test, but I do not understand why it does not work.
I correctly point the way?
https://github.com/HelloZeroNet/ZeroUp/blob/master/js/all.js#L2189-L2344

@DATSEC That code is compiled from CoffeeScript; you'd better copy ZeroFrame.js from https://github.com/HelloZeroNet/ZeroHello/blob/master/template-new/js/ZeroFrame.js and include it to index.html. Then:

var zeroFrame = new ZeroFrame();

var local_storage = {};
ZeroFrame.cmd("wrapperGetLocalStorage", [], function (res) {
    var key;
    for(key in local_storage) {
        if(!res.hasOwnProperty(key)) {
            delete local_storage[key] ;
        }
    }
    for(key in res) {
        local_storage[key] = res[key];
    }

    // put code which uses localstorage here
    // when you want to get from localstorage, use local_storage[key]
    // when you want to save to localstorage, use local_storage[key] = value; zeroFrame.cmd("wrapperSetLocalStorage", local_storage);
});

It is convenient for me to use the code that created CoffeeScript
Unfortunately, I still can not understand the API connections to my code.
I need a couple of examples to understand the principle of connection.
Can someone implement an example with the code that I threw off, with descriptions?
I need to add it here https://github.com/HelloZeroNet/ZeroUp/blob/master/js/all.js

I get different errors
Uncaught DOMException: Failed to read the 'localStorage' property from 'Window': The document is sandboxed and lacks the 'allow-same-origin' flag.

Uncaught TypeError: ZeroFrame.cmd is not a function

Uncaught ReferenceError: ZeroFrame is not defined

Uncaught SyntaxError: Unexpected identifier

Even when I just connect api LocalStorage, it still does not work as it should

You cannot reference localStorage direct. Please use ZeroFrame.
I can see that Page is used instead of ZeroFrame in your all.js
Maybe the fix is:

var local_storage = {};
Page.cmd("wrapperGetLocalStorage", [], function (res) {
    var key;
    for(key in local_storage) {
        if(!res.hasOwnProperty(key)) {
            delete local_storage[key] ;
        }
    }
    for(key in res) {
        local_storage[key] = res[key];
    }

    // put code which uses localstorage here
    // when you want to get from localstorage, use local_storage[key]
    // when you want to save to localstorage, use local_storage[key] = value; 

   Page.cmd("wrapperSetLocalStorage", local_storage);
});

Can we add rules to the client?
If it's safe.
https://github.com/HelloZeroNet/ZeroNet/blob/master/src/Ui/template/wrapper.html#L63

sandbox="allow-same-origin allow-top-navigation allow-forms allow-scripts"

It is unsafe. allow-same-origin allows you to escape iframe and do some bad things like shutdown ZeroNet/edit any zite/open ~infinity explorer.exe windows

@jaros1 Where should I install this code so that everything works?

@imachug I don't quite understand the principle of work.
For example, if I changed the source code from the sources.
How does he identify a fake zeronet from the present?

@DATSEC Sorry, I am not very good at OO and coffee script. Just using a JS version of ZeroFrame and strait ZeroFrame.cmd calls in my js code.
30-ZeroFrame.txt

@jaros1 Your code is no different from ZeroUP, I've already tried to add ZeroFrame.cmd to it
https://github.com/HelloZeroNet/ZeroUp/blob/master/js/all.js#L2198
I can not understand exactly where to add the code, so that it becomes active.
Although even if there are no errors, I still can not run localStorage

Not tested! Maybe you use Page instead of ZeroFrame?

'use strict';
// create 
let head = document.head,
    link = document.createElement('link');
link.rel = 'stylesheet';

ZeroFrame.cmd("wrapperGetLocalStorage", [], function (local_storage) {

    // put code which uses localstorage here
if (local_storage['themeStyle'] === 'dark') {
  link.href = 'css/dark.css'; // link to a dark style
  document.getElementById('switch-1').setAttribute('checked', true); // switch the checkbox to the "dark theme"
}
// default light theme
else {
  link.href = 'css/light.css'; // link to light style
}
head.appendChild(link); // insert the  into the header of the page between the head

// event when switching checkbox
document.getElementById('switch-1').addEventListener('change', ev => {
  let btn = ev.target;
  // if the checkbox is enabled
  if (btn.checked) {
    link.href = 'css/dark.css'; // turn off the dark theme
    local_storage['themeStyle'] = 'dark'; // write the value in localStorage
  }
  else {
    link.href = 'css/light.css'; // turn on the light theme
    local_storage['themeStyle'] = 'light'; // write the value in localStorage
  }

    // when you want to save to localstorage, use local_storage[key] = value; 
zeroFrame.cmd("wrapperSetLocalStorage", local_storage);
});
});

Does not work even if the script runs without error

ZeroFrame = (function(superClass) {
  extend(ZeroFrame, superClass);

  // code

});

Or I can not add it to ZeroFrame
Uncaught TypeError: ZeroFrame.cmd is not a function

@DATSEC Use Page instead of ZeroFrame.

@imachug Still not working (no errors)

@DATSEC Have you tried JS debugger? Should be possible to follow js execution line by line and call by call.

@jaros1
port.js:30
// "localStorage" gets cleared too often in Safari to rely on.
options = SAFARI ? safari.extension.settings : localStorage;

Uncaught DOMException: Failed to read the 'localStorage' property from 'Window': The document is sandboxed and lacks the 'allow-same-origin' flag
There are no other errors

There are no errors on the other browser

@DATSEC I am not using Safari but I don't think it is a safari issue. Anywhere I can see and test your code?

@jaros1
You can check for yourself
Add this code to ZeroUP

script.js

ZeroFrame = (function(superClass) {
extend(ZeroFrame, superClass);

'use strict';
// create
let head = document.head,
  link = document.createElement('link');
link.rel = 'stylesheet';

Page.cmd("wrapperGetLocalStorage", [], function (local_storage) {

  // put code which uses localstorage here
if (local_storage['themeStyle'] === 'dark') {
link.href = 'css/dark.css'; // link to a dark style
document.getElementById('switch-1').setAttribute('checked', true); // switch the checkbox to the "dark theme"
}
// default light theme
else {
link.href = 'css/light.css'; // link to light style
}
head.appendChild(link); // insert the  into the header of the page between the head

// event when switching checkbox
document.getElementById('switch-1').addEventListener('change', ev => {
let btn = ev.target;
// if the checkbox is enabled
if (btn.checked) {
  link.href = 'css/dark.css'; // turn off the dark theme
  local_storage['themeStyle'] = 'dark'; // write the value in localStorage
}
else {
  link.href = 'css/light.css'; // turn on the light theme
  local_storage['themeStyle'] = 'light'; // write the value in localStorage
}

  // when you want to save to localstorage, use local_storage[key] = value;
Page.cmd("wrapperSetLocalStorage", local_storage);
});
});

});

dark.css

body {
    background-color: #005aff;
}

light.css

body {
    background-color: red;
}

index.hml

<div class="switch">
  <input type="checkbox" id="switch-1" class="switch-check">
  <label for="switch-1" class="switch-label">
      <span class="switch-slider switch-slider-on"></span>
      <span class="switch-slider switch-slider-off"></span>
  </label>
</div>

<script type="text/javascript" src="js/script.js?=version=1.1" charset="UTF-8"></script>

Then you don't need ZeroFrame = (function(superClass) {:

'use strict';
// create
let head = document.head,
  link = document.createElement('link');
link.rel = 'stylesheet';

Page.cmd("wrapperGetLocalStorage", [], function (local_storage) {

  // put code which uses localstorage here
if (local_storage['themeStyle'] === 'dark') {
link.href = 'css/dark.css'; // link to a dark style
document.getElementById('switch-1').setAttribute('checked', true); // switch the checkbox to the "dark theme"
}
// default light theme
else {
link.href = 'css/light.css'; // link to light style
}
head.appendChild(link); // insert the  into the header of the page between the head

// event when switching checkbox
document.getElementById('switch-1').addEventListener('change', ev => {
let btn = ev.target;
// if the checkbox is enabled
if (btn.checked) {
  link.href = 'css/dark.css'; // turn off the dark theme
  local_storage['themeStyle'] = 'dark'; // write the value in localStorage
}
else {
  link.href = 'css/light.css'; // turn on the light theme
  local_storage['themeStyle'] = 'light'; // write the value in localStorage
}

  // when you want to save to localstorage, use local_storage[key] = value;
Page.cmd("wrapperSetLocalStorage", local_storage);
});
});

@jaros1

Shows this error
Uncaught ReferenceError: Page is not defined
either this
Uncaught ReferenceError: ZeroFrame is not defined

@DATSEC Do you put this file under <script src="all.js">?

I tried different ways, it does not help

Uncaught TypeError: Cannot read property 'cmd' of undefined

Uncaught ReferenceError: Page is not defined

Added this window.ZeroFrame = new ZeroFrame;
before new code. Still errors but localStorage is loaded from ZeroFrame API.

Maybe just missing some css files:
all.js?lang={lang}:3558 GET http://127.0.0.1:43110/1uPLoaDwKzP6MCGoVzw48r4pxawRBdmQc/css/light.css 404 (Not Found)
(anonymous) @ all.js?lang={lang}:3558
19:11:45.904 all.js?lang={lang}:25 [ZeroUp] Websocket callback not found: {cmd: "response", to: 14, result: undefined}
19:11:45.905 all.js?lang={lang}:25 [ZeroFrame] Websocket callback not found: {cmd: "response", to: 14, result: undefined}
19:11:46.662 all.js?lang={lang}:3554 GET http://127.0.0.1:43110/1uPLoaDwKzP6MCGoVzw48r4pxawRBdmQc/css/dark.css 404 (Not Found)
(anonymous) @ all.js?lang={lang}:3554
19:11:46.662 all.js?lang={lang}:25 [ZeroUp] Websocket callback not found: {cmd: "response", to: 15, result: undefined}
19:11:46.663 all.js?lang={lang}:25 [ZeroFrame] Websocket callback not found: {cmd: "response", to: 15, result: undefined}

window.ZeroFrame = new ZeroFrame;

ZeroFrame.cmd("wrapperGetLocalStorage", [], function (local_storage) {

    // put code which uses localstorage here
    if (local_storage['themeStyle'] === 'dark') {
        link.href = 'css/dark.css'; // link to a dark style
        document.getElementById('switch-1').setAttribute('checked', true); // switch the checkbox to the "dark theme"
    }
// default light theme
    else {
        link.href = 'css/light.css'; // link to light style
    }
    head.appendChild(link); // insert the  into the header of the page between the head

// event when switching checkbox
    document.getElementById('switch-1').addEventListener('change', function (ev) {
        var btn = ev.target;
// if the checkbox is enabled
    if (btn.checked) {
        link.href = 'css/dark.css'; // turn off the dark theme
        local_storage['themeStyle'] = 'dark'; // write the value in localStorage
    }
    else {
        link.href = 'css/light.css'; // turn on the light theme
        local_storage['themeStyle'] = 'light'; // write the value in localStorage
    }

    // when you want to save to localstorage, use local_storage[key] = value;
    Page.cmd("wrapperSetLocalStorage", local_storage);
});
});

Add files manually.
Look whether he remembers the actions on the click or not.

@jaros1 A bad idea! ZeroFrame MUST be a singleton, but it isn't in this case (1. your new ZeroFrame 2. ZeroUp's code)

@jaros1 It still does not work
Uncaught ReferenceError: ZeroFrame is not defined

Do you have the code working?

@DATSEC How do you run the code? :confused:

@imachug I make changes and update Zeronet site

@DATSEC Do you run this from console?

I'm using zeronet under the windows operating system

@DATSEC Do you run JavaScript from DevTools or do you edit index.html or do you edit all.js?

@imachug Edit files and update them
After I run zeronet and rewrite the code

@DATSEC Include <script type="text/javascript" src="js/script.js?=version=1.0" charset="UTF-8"></script> below all.js.

@imachug he was there from the very beginning, I did not delete it

That js/script.js couldn't be there from the very beginning! all.js could, but not script.js!

Can you give me your index.html please?

I managed to launch the API and it calls the css file.
but unfortunately it does not work he does not remember the choice.
constantly resets the button when I change the page.

Okay, that's better. Have you tried this code: https://github.com/HelloZeroNet/ZeroNet/issues/1399#issuecomment-383395060 ?

Yes, I tried
I get such errors

if (local_storage['themeStyle'] === 'dark') {
Uncaught TypeError: Cannot read property 'themeStyle' of null
Delete temporarily to get rid of the error

local_storage['themeStyle'] = 'dark'; // write the value in localStorage
Uncaught TypeError: Cannot set property 'themeStyle' of null

in fact, everything works correctly.
but the problem is that he does not remember

@imachug Seems to work, I do not know how it happened

@DATSEC I remember, ZeroNet has some caching. You should disable it in DevTools->Settings->Preferences->Disable HTTP cache (while DevTools is open).

Yes, I knew this so I cleaned my cache every 5 minutes

@DATSEC Interestingly, cleaning cache didn't work for me.

Thanks to all
very helped next I myself

Was this page helpful?
0 / 5 - 0 ratings

Related issues

HelloZeroNet picture HelloZeroNet  路  42Comments

0polar picture 0polar  路  57Comments

krixano picture krixano  路  59Comments

BenMcLean picture BenMcLean  路  39Comments

HelloZeroNet picture HelloZeroNet  路  36Comments