为什么使用了security 后台出不来了_一起来做Chrome/Firefox/Edge Extension《使用eval类方法》

b905de7e9ca984ce0b209d59c46c40fd.png

因为FireFox已经兼容了Chrome的Extension API,所以为Chrome制作的Extension可以几乎无缝的发布到FireFox里。但Firefox对代码的要求比Chrome要高,比如今天的主角eval类方法就不允许在Extension里使用,Chrome是可以使用的。本文就是介绍一下相关的内容以及如何去支持。

eval类方法

简单说明一下,eval类方法,除了eval还有new Function,这两个方法要在Extension里使用,需要在manifest.json里开启安全策略,如:

"content_security_policy": "'unsafe-eval'",

不然就会报错:

Uncaught EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self' blob: filesystem:".

再看看Firefox code review拒绝说明:

Extensions defining a content security policy that allows eval ('unsafe-eval') are generally not allowed for security and performance reasons. eval is only necessary in rare cases. Please use a different method.

所以,我们是无法在Firefox Extension(Add-ons)里使用eval类方法的。

为什么要使用eval类方法

最明显的原因,如:模板解析。我们知道,没有模板解析在渲染数据时会非常的麻烦和不好看,而大多数的模板解析都会使用eval来将字符串转为js function,以便调用。这其实是JS非常有优势的地方,几个简单的正则就可以有一整套模板解析机制。可惜无法简单的使用它们来帮助开发。

解决方法

使用沙盒模式

在Chrome的文档:Using eval in Chrome Extensions. Safely有讲解,如果使用沙盒模式来安全的使用eval的模板解析库,可以直接参考:https://developer.chrome.com/extensions/sandboxingEval

因为Firefox和Edge都是使用Chrome同种的Extension,所以肯定是通用的。

它的问题:

因为它实际是使用iframe模式,所以当你的模块拆分比较细的时候,并不好处理,而且不是所有Extension都好使用它,所以它肯定不是一个好的选择。

预编译模式

这其实也是Chrome推荐的一种方法,使用的时候先编译好,调用的是编译后的,这样就可以完全的避免使用eval类方法。但这里仍然有些问题,最主要是如何兼容开发/发布模式。这里可以有两种方法:

  1. watch监听文件修改,执行编译。很多库也有使用此方法
  2. 开发保持使用eval不变,发布编译时将其移除,同时编译模板,并更换调用的代码

我不是太喜欢watch监听的方式,因为不管怎么样,都有可能慢一拍,体验不好,所以选择第2种,也是YuiAPI使用的方法,简单说明。

开发的时候,保持使用eval不变

mainfest.json:

"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'"

解析:

evalViewFunc: function(model, name) {
    let key = model + "." + name;
    if (!this.hasOwnProperty(key)) {
        let content = this[model][name](),
            _html = [];
        let txt = ["App.view.extend('"+ model +"."+name+"', function() {"];
        txt.push("this.init = function(data) {");
        txt.push("var html = '';");
        content = content.split('n');
        for (let i in content) {
            _html.push(this.parse(content[i]));
        }
        txt.push(_html.join(""));
        txt.push("return html;");
        txt.push("}");
        txt.push("});");
        eval(txt.join(""));
    }
}

编译的时候

  1. 读取mainfest.json将content_security_policy去掉后,再生成新的mainfest.json文件
  2. 根据模板信息,编译生成一个view.js,将引用模板的调用去掉,最后引用view.js

这样发布后view.js会直接运行,而在开发中使用view的方法都没有问题。

可以参考:

https://github.com/yuiitsu/YuiAPI​github.com
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值