【问题标题】:Javascript: Store function in localstorageJavascript:在本地存储中存储功能
【发布时间】:2021-03-23 22:35:38
【问题描述】:

这可以插入到本地存储中还是有其他方法来存储它?

$('#pass_to_score').on('click',function(){

var compressed = function(){
    $('.whole_wrap_of_editcriteria').css('display','none');
    $('#wrappler').css('display','block');
    $('#li_addcriteria').css('display','none');
    $('#li_menu1').addClass('active');
    $('#home').removeClass('active');
    $('#menu1').addClass('active');
    $('#title_panel').html('Edit criteria scoring');
}
compressed();
localStorage.setItem('compressed', compressed());
//i also try set as JSON.stringify but its undefined

});

【问题讨论】:

  • 请注意,在该特定示例中,您实际保存在 localStorage 中的是函数的 result
  • 你应该保存数据,而不是保存代码,以便在需要时再次解析。
  • 通过在localStorage 行上的compressed() 之后使用括号,您实际上是在执行它并存储返回值(undefined)。你为什么要这样做?你想保留它以便以后执行它吗?解释用例,以便我们指导您找到更好的解决方案。
  • 我试图将这些代码保存为一个,而不是一个一个。只要我得到每一个价值,即使没有顺序。我可以在本地存储中一起执行它

标签: javascript jquery local-storage


【解决方案1】:

我不知道你为什么想要这样,我不推荐它,但你可以使用 toString 来做到这一点。

存储它:

var myFunc = function (){
  alert('Hello world!');
};

// Store it as a String
localStorage.setItem('compressedFunc', myFunc.toString());

稍后,检索它:

var compressedFunc = localStorage.getItem('compressedFunc');

// Convert the String back to a function
var myFunc = eval('(' + compressedFunc + ')');

// Use it
myFunc();

【讨论】:

  • 这会返回一个错误。 Uncaught SyntaxError: Unexpected token ( at <anonymous>:4:23
  • @RuanCarlos 谢谢,我需要在eval 中添加括号。这消除了错误
  • 虽然这确实可行(对于用户定义的函数),但它非常不安全,因为攻击者只需使用他们希望运行的自己的函数更改 localStorage。换句话说,请不要在生产中使用这样的代码。
【解决方案2】:

如果您有使用 JavaScript 编码的函数,则无需从 localStorage 恢复它,因为您已经拥有它。

您不能对函数进行 JSON 编码。您可以保存函数的源代码,并在检索时将eval 应用于它。但众所周知,这有一定的风险,在短语eval is evil”中捕捉到了。

如果你想发明一个对象结构来详细描述函数应该做什么,你可以稍微限制这种风险。在您的情况下,函数中的每个语句都是应用于 jQuery 选择器的方法。这可以用以下对象表示:

var compressed = [
    { selector: '.whole_wrap_of_editcriteria', method: 'css',         args: ['display', 'none'] },
    { selector: '#wrappler',                   method: 'css',         args: ['display', 'none'] },
    { selector: '#li_addcriteria',             method: 'css',         args: ['display','none'] },
    { selector: '#li_menu1',                   method: 'addClass',    args: ['active'] },
    { selector: '#home',                       method: 'removeClass', args: ['active'] },
    { selector: '#menu1',                      method: 'addClass',    args: ['active'] },
    { selector: '#title_panel',                method: 'html',        args: ['Edit criteria scoring'] }
];

然后你的实际函数,可以将该对象作为其输入,并对其进行处理,从而产生相同的效果:

var applyInstructions = function(instructions) {
    instructions.forEach( cmd => $(cmd.selector)[cmd.method](...cmd.args) );
}

现在,当你想把这些知识保存到localStorage,你只需要存储上面构造的对象,像这样:

// save to localStorage:
localStorage.setItem('compressed', JSON.stringify(compressed));

在检索到它之后,您将对其执行通用函数:

// get from localStorage:
applyInstructions(JSON.parse(localStorage.getItem('compressed')));

这类似于使用eval,但它的优点是您可以限制可以执行的内容(在applyInstructions 中)。例如,您可以检查method 属性是否应该只是值cssaddClassremoveClasshtml 之一,尽管最后一个可能是危险的。如果可能,text 会是更好的选择。

下面是更安全的applyInstructions 的样子:

var applyInstructions = function(instructions) {
    if (instructions.some( 
            cmd => ['css','addClass','removeClass','textContent'].indexOf(cmd.method)==-1)) {
        throw "Invalid instructions object";
    }
    instructions.forEach( cmd => $(cmd.selector)[cmd.method](...cmd.args) );
}

【讨论】:

    猜你喜欢
    • 2014-02-12
    • 2021-11-25
    • 1970-01-01
    • 2015-05-16
    • 2021-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-02
    相关资源
    最近更新 更多