Alternatives for Javascript eval [duplicate]

风流意气都作罢 提交于 2019-12-18 01:12:07

问题


Mozilla's Content Security Policy disallows the use of javascript eval function as well as inline scripts. They claim that all instances of eval can be replaced by another (hopefully safer) function. I agree in most scenarios, Javascript eval can be replaced, but I'm not sure whether the replacement is possible for every case.

My question is twofold:

  1. Is there a generic way to replace every javascript eval function? (doesn't have to be safe)
  2. Is there a case where the Javascript eval cannot be replaced?

回答1:


The most common uses which can be substituted are the following ones. I would certainly use these first.

  1. Accessing dynamic properties

    Do use: obj[keyAsVariable]

    Don't use eval('obj.' + keyAsVariable)

  2. Parsing JSON

    Do use JSON.parse(data)

    Don't use eval('(' + data + ')')

  3. Calculating user input

    Do use a certain library

    Don't use eval(input)

If really necessary, you can also send the script to a server which simply echoes it back, and you can request it as a script tag. It won't use eval but still execute it. It isn't safe as it's sent twice over the Internet.

var s = document.createElement('script')
s.src = 'request_script?data=' + data;
document.getElementsByTagName('head')[0].appendChild(s);

request_script could be a file implemented in PHP, like the following. Again, it's bad practice but is a generic way of circumventing eval.

<?
echo $_GET['data'];
?>

You could say that this also automatically answers your second question with 'no'.




回答2:


You could wrap the java script within a function call similar to JSONP and then dynamically create a script tag to load that.




回答3:


Load as script using a Blob

Instead of using eval you can also use a Blob and load the code as if it was an external js file: To ensure that functions or variables that are inside the code that you are loading are available you need to use a callback method that will be triggered onload event.

var code = "console.log('hello world');";

// With eval:
eval(code);

// With a blob:
var blob = new Blob([code], {type: 'text/javascript'});
var urlCreator = window.URL || window.webkitURL;
var url = urlCreator.createObjectURL( blob );

function loadScript(url, callback)
{
    // Add a the script tag to the head
    var head = document.getElementsByTagName('head')[0];
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = url;

    // Bind the callback (depends on browser compatibility).
    script.onreadystatechange = callback;
    script.onload = callback;

    // Load the script
    head.appendChild(script);
}

// Any variables or methods inside the code will be on callback.
loadScript(url, callback);

Note Be aware that the danger for code injection is similar to eval.



来源:https://stackoverflow.com/questions/7127652/alternatives-for-javascript-eval

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!