1

On my HTML page, I have an AJAX Post to get some data. The returned data contains a string, and the content of this string is raw javascript.

$.ajax({
    url: '@Url.Action("GetPropertyDataForInstance", "Local_Data")',
    type: 'POST',
    dataType: 'json',
    data: instancePropertyRequest,
    contentType: 'application/json; charset=utf-8',
    success: function (response) {

        var javscriptRawString = response.javascriptToExecute;   
        var alertString = response.data;
    }
})

The content of javscriptRawString:

alert(alertString);

After I get this javascriptRawString, what do I do so that I can directly execute the javascript inside??

Charlie Ou Yang
  • 631
  • 7
  • 16
  • 5
    That's what `eval` does. Beware of security holes. – SLaks Oct 31 '13 at 16:15
  • 1
    Rather than return script and `eval` it (which is a security nightmare, and really nasty code), why not return the string `hello there` and `alert` it within the `success` handler. – Rory McCrossan Oct 31 '13 at 16:17
  • I really doubt that 'hello there' alert is the code he wants in the end. Probably just to test the response. But ya... if you can do anything to avoid `eval`, do it. And chances are you can easily avoid `eval` – nzifnab Oct 31 '13 at 16:18
  • if you pass in a function name you could execute it using `window[javscriptRawString]();` – Pete Oct 31 '13 at 16:27

3 Answers3

4

this is slightly better than eval as eval is evil ;)

(new Function(response.data))()

Using eval is evil because there can be lots of security holes. You are executing code in global scope. Function takes of this differently by executing in its own scope.

new Function is also faster

in your case

$.ajax({
    url: '@Url.Action("GetPropertyDataForInstance", "Local_Data")',
    type: 'POST',
    dataType: 'json',
    data: instancePropertyRequest,
    contentType: 'application/json; charset=utf-8',
    success: function (response) {

        (new Function(response.data))()   

    }
})

new Function creates a new function from a raw text.

()() executes the function immediately

i would also add some extra checks and headers if you get your functions with ajax. check this.

https://stackoverflow.com/a/17468822/2450730

edit

if you want to pass params from ajax

//raw ajax response
var x='param';
alert(x)

if you want to pass params from inside the ajax (not good.)

success: function (response) {
 var x='param';
 (new Function(response.data))(x)   
}

raw

alert(x);

edit 2

if you get a object with 1.the script 2.the params

then you need to define a argument name.in this case 'x'.

js

 (new Function('x',response.script))(response.param)

RAW response.script

 alert(x)

more arguments:

(new Function('a','b','c','alert(a+b+c)'))(1,2,3) // 123

TEST IT ... http://jsfiddle.net/pLQzd/ READ IT ... https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function scroll to the bottom.

but as you get the object containing the function and the vars... from the same ajax call

i would simply create something already described.

RAW

var param='hello';
alert(param);

or even simpler

alert('hello');
Community
  • 1
  • 1
cocco
  • 16,442
  • 7
  • 62
  • 77
  • If there's data in the that I need to pass into the new generated function, how do I do that? I understand (new Function(response.data))() creates a new function based on the string in response.data, but how do I pass a parameter in there? I tried (new Function(response.data))(anotherVar), but this doesn't work :( – Charlie Ou Yang Oct 31 '13 at 16:45
  • what you mean ? extend you question...from where you getthe params? – cocco Oct 31 '13 at 16:46
  • I mean I want to pass a variable into this newly generated function. In this function I need this variable to perform some other assignments. – Charlie Ou Yang Oct 31 '13 at 16:49
  • ajaxRaw: var x='banana';alert(x) – cocco Oct 31 '13 at 16:50
  • In my response, it's list of objects. These objects have a key and value. So in this case, I have two objects in the response. One object is key="script", value="return 5 + valueForFunction;" The other object has the data, key="data", value=1. So this is something that I want to do: var functionString = response.data.get("script"); var valueForFunction = response.data.get("data"); var myFunction = (new Function(functionString)); myFunction(valueForFunction); – Charlie Ou Yang Oct 31 '13 at 16:56
  • post a example raw response by extending your question. – cocco Oct 31 '13 at 16:58
  • I edited the original question. Thanks for your help – Charlie Ou Yang Oct 31 '13 at 17:07
  • Can you please clarify x?? – Charlie Ou Yang Oct 31 '13 at 17:25
  • 1
    function (x) {alert(x)} ... x is just the name for the first argument.more arguments : (new Function('a','b','c','alert(a+b+c)'))(1,2,3) – cocco Oct 31 '13 at 17:28
2

You can run any string via eval:

eval('alert("hello world")');

Make sure you know exactly what you're evaling though.

lxe
  • 7,051
  • 2
  • 20
  • 32
  • "Make sure you know exactly what you're evaling though." – lxe Oct 31 '13 at 18:59
  • Yes, I've read that. Still, I would be careful recommending `eval`, especially to beginners, since they are all too likely to ignore any disclaimers and warnings.. – lethal-guitar Oct 31 '13 at 20:51
0

Why would you not format your ajax response with integers?

e.g.

$.ajax({
    //Your AJAX
}).done(function(response) {
    //Let's say response from the script is 1.

    switch(response) {
        case 1:
            alert('Hello world');
            break;

        //case ... etc.
    }

});

NEVER use eval(); unless you have absolutely no other choice.

eval === evil!

SidOfc
  • 4,552
  • 3
  • 27
  • 50
  • There is almost always a better method than using `eval`. If we knew his actual problem and not this made-up problem I'm sure we could give him a proper answer... – nzifnab Oct 31 '13 at 16:21
  • 3
    "Why would you not format your ajax response with integers?" Why **would** you? – Anthony Grist Oct 31 '13 at 16:22
  • @nzifnab you are entirely correct, lets just hope the OP follows this example to start with and to avoid `eval();`ling possibly viscious code. – SidOfc Oct 31 '13 at 16:23
  • @AnthonyGrist because scripts, for instance when handling database requests could easily return an integer to work with and is very easy to identify, ofcourse if you expect a response with data, use JSON to return it, but in this particular case, we do not know what the OP needs. – SidOfc Oct 31 '13 at 16:25
  • I'm not a big fan of this "potentially massive switch statement" and some obscure number code that does magical things. But there's no reason you can't return a JSON data structure and perform actions based on that – nzifnab Oct 31 '13 at 16:26
  • @SidneyLiebrand They could also easily return pretty much anything else. There's zero reason to suggest that returning an integer that's arbitrarily mapped to a string of code using a `switch` statement is a better, or even good, approach. – Anthony Grist Oct 31 '13 at 16:29
  • I never mentioned 'better' or 'good', And as mentioned, we do not know what the OP gets back, hence the integer, there is no downside to using one either, just a suggestion for further processing anyways. and if an Ajax call returns alot of different responses, I'd recommend using a function that handles ajax responses rather than a switch statement. – SidOfc Oct 31 '13 at 16:32