执行从ajax调用返回的js时避免eval [英] Avoiding eval when executing js returned from ajax call

查看:94
本文介绍了执行从ajax调用返回的js时避免eval的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想进行一个返回json对象的ajax调用。其中一个JSON对象的属性将是要在客户端中执行的函数的字符串。我意识到这可以通过使用eval轻松解决,但是看到很多 缺点对于评估,我宁愿避免它。我的问题是:

I want to make an ajax call that will return a json object. One of this JSON object's properties will be the string of a function to be executed in the client. I realise this can easily be solved by using eval, but seeing the many disadvantages of eval, I'd rather avoid it. My question is:

我能以某种方式从服务器返回一些js代码并执行它而不需要求助于eval吗?

Can I in some way return from the server some js code and execute it without resorting to eval?

根据要求,这里是一些示例代码:

As requested, here's some example code:

服务器(Node.js):

Server (Node.js):

var testFunc = function() {
    alert('h1');
};

app.get('/testPack', function(req, res) {
    var template = jade.render('h1 hi');
    res.send({
        template : template,
        entity : testFunc.toString(),
        data : { 
            id: "OMG I love this"
        }
    });
});

客户:

$(document).ready(function() {
    $.ajax({
        url: '/testPack',
        success: function(data) {
            $('body').append($(data.template))
            alert(data.data.id);
            var entity = eval(data.entity);
            entity();
        }
    })
})

当然,被称为实体的返回函数不会做这么愚蠢的事情,它会暴露返回小部件的API。

Of course, the returned function called entity wouldn't do such a silly thing, it would expose an API of the returned widget.

为了澄清,我想避免不得不单独调用javascript本身。我宁愿将它与要渲染的模板和数据捆绑在一起。

Just to clarify, I'd like to avoid having to make a separate call for the javascript itself. I'd rather bundle it with the template and data to render.

推荐答案

最简单的方法就是不要打电话给服务器通过ajax,而是在页面上创建一个新的脚本标记,其中url指向一个RESTful web服务,该服务将输出纯JavaScript(而不是JSON)。这样你的输出将由浏览器直接评估而不使用eval。

Easiest way to do that, is not to call a server through an ajax, but instead to create a new script tag on the page with the url pointing to a RESTful web-service that would output pure JavaScript (not JSON). That way your output will be evaluated by the browser directly without the use of eval.

为了扩展我的答案:
解决问题在全局上下文中运行脚本你可以做一些技巧。例如,当您向头部添加脚本标记时,您可以绑定onload事件(或者更确切地说是假的onload事件,因为IE不支持脚本标记上的onload),并且如果您的服务器响应始终是包含在具有已知名称的函数中,您可以在对象中应用该函数。下面的示例代码(这只是一个例子):

To expand a little on my answer: To get around the problems of running script in the global context you could do some tricks. For example, when you are adding script tag to the head, you can bind onload event (or rather fake onload event, since IE doesn't support onload on the script tag) to it, and if your response from the server will be always wrapped in the the function with a known name, you could apply that function from within your object. Example code below (this is just an example though):

function test ()
{
    this.init = function ()
    {
        var script = document.createElement("script");
        script.type = "text/javascript";
        script.language = "javascript";
        script.src = "test.js";
        var me = this;
        window.callMe = function () { me.scriptReady(me); };
        var head = document.getElementsByTagName("head")[0];
        head.appendChild(script);
    };

    this.scriptReady = function (object)
    {
        serverResponse.call(object);
    };

    this.name = "From inside the object";

    this.init();
}

var t=new test();

服务器响应应如下所示:

The server response should look something like this:

function serverResponse()
{
    alert(this.name);
}

window.callMe();

在这种情况下,serverResponse()内的所有内容都将您的对象用作this。现在,如果您以这种方式修改服务器响应:

In this case, everything inside serverResponse() will use your object as "this". Now if you modify your server response in this way:

function serverResponse()
{
    this.serverJSONString = { "testVar1": "1", "testVar2": 2 };

    function Test()
    {
        alert("From the server");
    }

    Test();
}

window.callMe();

您可以从服务器返回多个内容,只需一个响应。如果您不喜欢只设置变量,那么在主对象中创建一个函数来处理您可以通过从响应中调用此函数来提供的JSON字符串。

You can have multiple things being returned from the server and with just one response. If you don't like just setting variables, then create a function in your main object to handle JSON string that you can supply by calling this function from your response.

As你可以看到,这一切都是可行的,它看起来并不漂亮,但是再一次,你要做的事情并不是很好。

As you can see, it's all doable, it really doesn't look pretty, but then again, what you are trying to do is not pretty to begin with.

PS只是在标签内插入一个字符串不适用于IE,它不允许你这样做。如果您不必支持IE,那么您可以在新创建的脚本标记中插入服务器响应并完成它。

P.S. Just inserting a string inside tag will not work for IE, it will not allow you to do that. If you don't have to support IE, then you could get away with just inserting server response inside a newly created script tag and be done with it.

P.P.S。请不要按原样使用此代码,因为我没有花太多时间写它。这很丑陋,但只是作为一个例子: - )

P.P.S. Please don't use this code as is, cause I didn't spend too much time writting it. It's ugly as hell, but was just ment as an example:-)

这篇关于执行从ajax调用返回的js时避免eval的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆