简体   繁体   English

document.body.appendChild(script) 与 eval()

[英]document.body.appendChild(script) vs eval()

I have the following two options to run a script with a string:我有以下两个选项来运行带有字符串的脚本:

Option A:选项 A:

var script = document.createElement('script');
script.innerHTML = "function foo(){console.log('Hello!')}";
script.type = "text/javascript";
document.body.appendChild(script);
foo();

Option B:选项 B:

eval("function foo(){console.log('Hello!')}");
foo();

They both print Hello in the console.他们都在控制台中打印Hello

If I want to let users dynamically run scripts in my app, which one is a better(safer, faster) option?如果我想让用户在我的应用程序中动态运行脚本,哪一个是更好(更安全、更快)的选项?

If I want to let users dynamically run scripts in my app...如果我想让用户在我的应用程序中动态运行脚本......

There's nothing safe with this requirement, and none of the options is CSP friendly.这个要求没有什么安全的,而且没有一个选项对CSP友好。

The " best " approach you could use though is Function , 'cause at least that doesn't reaches/target the local scope, like eval would do, keeping the execution within its function body scope. The " best " approach you could use though is Function , 'cause at least that doesn't reaches/target the local scope, like eval would do, keeping the execution within its function body scope.

The question now would be how to make the code available to the user without interfering with the rest of the code, or the previous call, or the global scope.现在的问题是如何在不干扰代码的 rest 或先前调用或全局 scope 的情况下使用户可以使用代码。

For this specific case I suggest a CommonJS like approach, so that your users must define what they are exporting in their code.对于这种特定情况,我建议使用类似CommonJS的方法,以便您的用户必须定义他们在代码中导出的内容。

Example例子

const CommonJS = code => {
  const exports = {};
  const module = {exports};
  const runtime = Function(
    'module', 'exports',
    `"use strict";${code};return module`
  );
  return runtime(module, exports);
};

const {exports} = CommonJS(`
  module.exports = function foo(){console.log('Hello!')}
`);

exports();

Using this approach your users can define a single, or multiple, exports, like in Node.js, becoming familiar with the CommonJS module system, and avoiding any sort of global scope pollution, thanks to the "use strict" directive and the Function closure itself.使用这种方法,您的用户可以定义单个或多个导出,例如在 Node.js 中,熟悉 CommonJS 模块系统,并避免任何类型的全局 scope 污染,这要归功于"use strict"指令和 Z86408593C34AF77FDD1ZF90DF93 本身。

Alternatively, you can const foo = Function('return(' + code + ')')() but that requires code to be a single expression, so I would personally stick with the previous approach.或者,您可以const foo = Function('return(' + code + ')')()但这要求code是单个表达式,所以我个人会坚持以前的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM