2012-02-07 73 views
0

我正在嘗試做一些動態加載,包括javascript,css和html文件。訪問jquery中的數據.when .done函數(也是eval那個邪惡?)

我願做這樣的:

$.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"); 
}); 

所以我對我如何分離出響應回調困惑。目前,您在我的.done函數中看到的響應對象只是我調用的HTML文件。此函數正在進行正確的ajax調用,並且服務器正在響應正確的文件,但是一旦完成所有調用,如何訪問它們?因此,我不會將css/js應用於尚未存在的HTML等。另外,我所做的是將javascript文件作爲字符串返回,然後在ejval()函數中執行它。我的理解是,這是一個可以使用的eval,因爲它的文件被我們自己的服務器返回,所以我不知道它是如何被篡改的。這個假設是否正確?

此外,在我的appendCss函數中,我只是將它添加到頭部的「樣式」元素。這有什麼大問題嗎?我正在使用所有這些來創建「基於窗口小部件/應用程序的」功能,其中我爲每個「應用程序」都有一個js,css和html,並且我只想在需要時查詢服務器,並在應用程序加載時。

回答

3

如果您的下載數據是從原始網頁上的相同服務器中檢索的,那麼一般情況下,您在該代碼中的信任級別與您在瀏覽器中運行的代碼中的信任級別相同。

在這樣的上下文中,eval()的問題不一定是您不相信自己的服務器返回的代碼;這是有人可能會改變運行的JavaScript,以便javascriptPath變量指向你不指望的地方。


至於你的實際問題去,你的done回調實際上將通過三個參數,因爲您的通話when包括三項承諾。

由於您定義回調的方式(如function(response)),您只能看到第一個 - 來自HTML調用的返回值。其他兩個參數被忽略。

您正在傳遞的三個參數中的每一個都是由三個元素組成的數組:[wasSuccessful, statusText, jqxhr]。做一些與他們有用,你可以組織你的回調是這樣的:

$.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); 
    } 
}) 

(假設你已經寫了適當appendHtmlappendCssexecuteJs功能)


有一些本頁上的很好的例子:http://api.jquery.com/jQuery.when/

而且這個頁面有關於jqxhr對象的文檔(每個數組中的第三個元素傳遞給你完成的函數http://api.jquery.com/jQuery.ajax/#jqXHR

+0

你有建議如何處理這個問題嗎?或者你的建議是不要使用eval? – Evan 2012-02-07 17:08:15

1

要訪問所有的迴應只是傳遞三個參數到done()回調。試試這個:

$.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]); 
}) 

,如果你嘗試打印內部完成(arguments對象),你可以清楚地看到,所有的答覆都傳遞到回調

+0

+1這個作品,謝謝。我可以發誓我試圖做到這一點不知道我是如何搞砸的:XI會接受這個答案,一旦我給了一點時間,看看我能得到任何答案我的側軌問題 – Evan 2012-02-07 17:19:30

0

關於使用eval,可以考慮使用JSONP代替(dataType: 'jsonp' )。這種方式jQuery負責爲您執行代碼。我想jQuery也使用了引擎蓋下的eval(),但至少你知道它是以適當的方式完成的。關於安全性,如果你還沒有看到關於何時eval()是邪惡的相關問題。

+0

jquery執行它作爲一旦它加載,而我希望它等到html已被檢索並放在頁面上 – Evan 2012-02-07 19:00:25