Problem: Ajax request within phantomJs script to a local page doesn't work (no response)
Question: How can I make it work? Any ideas or possible solutions?
Description: I'm running a phantomJs script and I need to access some data that is provided by a php function in another page (local). In order to do that, I use an ajax request to that page inside the phantomjs script. However, the request doesn't do anything. The script is:
page.open(url, function (status) {
page.includeJs('http://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js', function () {
console.log("Solve Captcha");
$.ajax({
url: 'captcha.php',
data: { filename: 'C:\\wamp\\www\\images\\0.png' },
type: 'post',
success: function (output) {
console.log('Solved');
phantom.exit();
},
});
});
});
The php page is in a local WAMP server and it has been tested with ajax (outside a phantomJs script), and it works fine. The script and the php files are in the folder C:\wamp\www
, while the image 0.png
is in the sub-folder C:\wamp\www\images
.
Important: The page captcha.php
is in the localhost, while phantomJs is requesting a page that is not local, that is, page.open
opens a url
that is not local.
I don't understand why making this request in a phantomJs script won't work. Could you please help me?
page.includeJs()
injects jQuery into the page, so it is only accessible from the page context (inside of page.evaluate()
). The page context is sandboxed, so you cannot call phantom.exit()
from the page context, because there is no such object window.phantom
.
You have two possibilities to make it work.
Blocking AJAX
jQuery.ajax()
accepts an async: false
property to make a blocking AJAX call, so you can simply make the call and then continue with the execution in iterative style.
page.open(url, function (status) {
page.includeJs('http://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js', function () {
console.log("Solve Captcha");
page.evaluate(function(){
$.ajax({
async: false, // this
url: 'http://localhost/captcha.php',
data: { filename: 'C:\\wamp\\www\\images\\0.png' },
type: 'post',
success: function (output) {
console.log('Solved');
},
});
});
phantom.exit();
});
});
Wait for completion
waitFor
from the examples can be used to wait for a specific condition to be set. This condition should be set in the success
callback of the AJAX call:
page.open(url, function (status) {
page.includeJs('http://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js', function () {
console.log("Solve Captcha");
page.evaluate(function(){
window._finishedCall = false;
$.ajax({
url: 'http://localhost/captcha.php',
data: { filename: 'C:\\wamp\\www\\images\\0.png' },
type: 'post',
success: function (output) {
console.log('Solved');
window._finishedCall = true;
},
});
});
waitFor(function check(){
return page.evaluate(function(){
return window._finishedCall;
});
}, function onReady(){
phantom.exit();
}, 10000); // 10 seconds maximum timeout
});
});
The second problem is that you want to make a cross-domain request, because captcha.php
is on localhost and url
is distinct from localhost. You need to run PhantomJS with the --web-security=false
option and use fully qualified URLs: http://localhost/captcha.php
.