I am attempting to do some dynamic loading that includes javascript, css, and html files.
I would like to do it like this:
$.when($.ajax(htmlPath), $.get(cssPath), $.ajax({
url: javascriptPath,
dataType: "text"
}))
.done(function(response){
// i want to pass the data for each of these to the respective functions
appendHtml(what goes here??);
appendCss(what goes here??);
executeJs(what goes here??);
})
.fail(function(){
console.log("failed");
});
So I'm confused on how I separate out the response callbacks. Currently, the response object you see in my .done function is ONLY the HTML file which I called. This function is making the correct ajax calls, and the correct files are all being responded by the server, but how do I access them once ALL the calls are plete? Need this so I won't be applying css/js to HTML which is not there yet, etc. Also, what I do is have the javascript file returned as a string and then i eval() it within the executeJs function. My understanding is that this is an okay use of eval because its the file being returned by our own server so I don't see how it could be tampered with. Is this assumption correct?
Furthermore, in my appendCss function, I'm just adding it to a "style" element in the head. Is there a big issue with this? I am using all this to make a "widget/app based" functionality where I have a js,css,and html for each "app", and I just want to query the server for them when they are needed and the app is loading.
I am attempting to do some dynamic loading that includes javascript, css, and html files.
I would like to do it like this:
$.when($.ajax(htmlPath), $.get(cssPath), $.ajax({
url: javascriptPath,
dataType: "text"
}))
.done(function(response){
// i want to pass the data for each of these to the respective functions
appendHtml(what goes here??);
appendCss(what goes here??);
executeJs(what goes here??);
})
.fail(function(){
console.log("failed");
});
So I'm confused on how I separate out the response callbacks. Currently, the response object you see in my .done function is ONLY the HTML file which I called. This function is making the correct ajax calls, and the correct files are all being responded by the server, but how do I access them once ALL the calls are plete? Need this so I won't be applying css/js to HTML which is not there yet, etc. Also, what I do is have the javascript file returned as a string and then i eval() it within the executeJs function. My understanding is that this is an okay use of eval because its the file being returned by our own server so I don't see how it could be tampered with. Is this assumption correct?
Furthermore, in my appendCss function, I'm just adding it to a "style" element in the head. Is there a big issue with this? I am using all this to make a "widget/app based" functionality where I have a js,css,and html for each "app", and I just want to query the server for them when they are needed and the app is loading.
Share Improve this question edited Feb 7, 2012 at 16:53 Colin Brock 21.6k9 gold badges49 silver badges62 bronze badges asked Feb 7, 2012 at 16:51 EvanEvan 6,1039 gold badges35 silver badges64 bronze badges3 Answers
Reset to default 3If your downloaded data is being retrieved from the same server as your original web page, then yes, generally, you would have the same level of trust in that code as you do in the code that's already running in the browser.
The problem with eval()
in a context like this isn't necessarily that you don't trust the code ing back from your own server; it's that someone might be able to alter the running javascript so that the javascriptPath
variable points somewhere you didn't expect it to.
As far as your actual question goes, your done
callback will actually be passed three parameters, because your when
call included three promises.
Because of the way that you defined your callback (as function(response)
), you are only seeing the first one -- the return value from the HTML call. The other two parameters are being ignored.
Each of the three parameters that you are being passed will be an array of three elements: [wasSuccessful, statusText, jqxhr]
. To do something useful with them, you could structure your callback something like this:
$.when($.ajax(htmlPath), $.get(cssPath), $.ajax({
url: javascriptPath,
dataType: "text"
}))
.done(function(htmlResponse, cssResponse, jsResponse){
if (htmlResponse[0]) {
appendHtml(htmlResponse[2].responseText);
}
if (cssResponse[0]) {
appendCss(cssResponse[2].responseText);
}
if (jsResponse[0]) {
executeJs(jsResponse[2].responseText);
}
})
(Assuming that you have the appropriate appendHtml
, appendCss
, and executeJs
functions written already)
There are some good examples on this page: http://api.jquery./jQuery.when/
And this page has the documentation on the jqxhr object (the third element in each of the arrays that are passed to your done function): http://api.jquery./jQuery.ajax/#jqXHR
To access to all the responses just pass three arguments to the done()
callback. Try this:
$.when($.ajax(htmlPath), $.get(cssPath), $.ajax({
url: javascriptPath,
dataType: "text"
}))
.done(function(responseHTML, responseCSS, responseJS){
console.log(responseHTML[0]);
console.log(responseCSS[0]);
console.log(responseJS[0]);
})
if you try to print arguments
object inside done() you can clearly see that all the responses are passed into the callback
Regarding the use of eval, consider using JSONP instead (dataType: 'jsonp'
). This way jQuery takes care of executing the code for you. I suppose jQuery also uses eval()
under the hood, but then at least you know that it is done in a proper manner. With respect to safety, also see the related question on when eval() is evil if you haven't already.