2015-01-20 51 views
5

我正在嘗試使用jquery和phantomjs。我嘗試了一個獨立的例子,它工作正常。下面是我所做的:未包含在PhantomJs中的JQuery

var page = require('webpage').create(); 
    page.open("http://www.phantomjs.org", function(status) { 

    page.onConsoleMessage = function(msg) { 
     console.log("message recvd: " + msg); 
    }; 

    var result; 

    page.includeJs("https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js", function() { 
     console.log("loading jquery"); 
    }); 

    setTimeout(function() { 
     page.evaluate(function() { 
     console.log("$(\"title\").text() -> " + $("title").text()); 
     }); 
    }, 1000); 
} 

這是我得到的輸出:對評價功能,因爲includeJs()將執行

loading jquery 
message recvd: $("title").text() -> PhantomJS | PhantomJS 

在上面的代碼片斷中,我已經使用的setTimeout()異步,需要一些時間來加載jQuery。如果我不使用setTimeout()或者使用一個很小的超時值,它不起作用。

但是,當我在我的應用程序中嘗試相同的代碼時,它不起作用。以下是我有:

var baseSetup = function(guid, page, config, request, response) { 
    /* enable the console output inside the callback functions */ 
    page.onConsoleMessage = function (msg) { 
    console.log(guid + ": console msg: " + msg); 
    }; 

    /* used for ignoring potential alert messages when evaluating js code */ 
    page.onAlert = function (msg) { 
    console.log(guid + " (alert): alert msg: " + msg); 
    }; 

    /* suppress the error messages */ 
    page.onError = function(msg, trace) { 
    var msgStack = ['ERROR: ' + msg]; 
    if (trace && trace.length) { 
     msgStack.push('TRACE:'); 
     trace.forEach(function(t) { 
     msgStack.push(' -> ' + 
     t.file + 
     ': ' + 
     t.line + 
     (t.function ? ' (in function "' + t.function + '")' : '')); 
     }); 
    } 
    console.error(guid + ": " + msgStack.join('\n')); 
    }; 
} 

module.exports = function extractionDriver(responseFromUrl, responseToUser, page, request) { 
    console.log(page.customHeaders['guid'] + ": extractionDriver, status = " + responseFromUrl.status); 

    if(page.isLocalFile || responseFromUrl.status !== 0) 
    { 
    var viewportStr = page.customHeaders['viewportStr']; 
    console.log(page.customHeaders['guid'] + ": Setting viewport size: " + viewportStr); 
    var viewportObj = parseViewport(viewportStr); 
    page.viewport = viewportObj; 

    page.evaluate(function(w,h) { 
     document.body.style.width = w + "px"; 
     document.body.style.height = h + "px"; 
    }, viewportObj.width, viewportObj.height); 

    page.includeJs("https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js", function() { 
     console.log("loading jquery"); 
    }); 

    setTimeout(function() { 
     page.evaluate(function() { 
     console.log("$(\"title\").text() -> " + $("title").text()); 
     }); 
    }, 1000); 
    } 

這是我所看到的,當我運行我的應用程序:

d8db6045-a0e8-11e4-a619-6949593d958d: ERROR: ReferenceError: Can't find variable: $ 
TRACE: 
-> phantomjs://webpage.evaluate(): 3 
-> phantomjs://webpage.evaluate(): 4 
-> phantomjs://webpage.evaluate(): 4 

日誌行「加載jQuery的」從不打印,並且永遠不會加載jQuery的。我試過在includeJs()的回調函數內部封裝evaluate()函數,但是也沒有工作(沒有控制檯日誌打印)。

這裏可能會出現什麼問題?請讓我知道我是否應該提供更多信息。

回答

7

這就是爲什麼page.includeJs有一個回調,所以你可以把取決於jQuery的代碼放在那裏。當引用的JavaScript已經被加載時,該回調被調用。歡迎來到通向回撥地獄之路的另一層。

我曾經歷過一次,但是由於某種原因,這沒有奏效。解決方法是在includeJs回調中設置全局變量,並使用waitFor等待全局變量設置在includeJs回調之外。

var _loadIndicator = false; 
page.includeJs("https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js", function() { 
    _loadIndicator = true; 
}); 

waitFor(function check() { 
    return _loadIndicator; 
}, function onReady() { 
    page.evaluate(function() { 
    console.log("$(\"title\").text() -> " + $("title").text()); 
    }); 
}, 10000); 
+0

這就是,如果你想遠程得到它......如果它的服務器已經在和你只是想包括jquery .min fiile ...你會使用injectJs ...但它仍然不適合我 – carinlynchin 2016-07-27 20:19:50

+0

@Carine我不知道你的意思是「服務器」,但是'page.injectJs'只有在文件是可通過文件路徑訪問。如果不是,那麼它必須通過一個URI來訪問,在這種情況下必須使用'page.includeJs'。 – 2016-07-27 20:38:48

+0

是的,我知道..但即使我有 page.injectJs('jquery.min.js'),我仍然收到錯誤「無法找到變量:$」 – carinlynchin 2016-07-28 10:29:35

0

我只是有這個煩惱,但我的錯誤是,我試圖phantom.injectJs,不page.injectJs(衝擊)。然後,如果statussuccess,把

page.injectJs('lib/jquery.min.js'); 

,並嘗試

page.evaluate(function(){ 
    console.log($("body").length); 
});