OnResourceReceived is not fired after a synchronous ajax request #11284
Comments
I believe that this duplicates #10498 |
@igormukhin: I'm assuming you meant |
@JamesMGreene Yes, |
I will try to describe my situation. I have to render a screenshot of a webpage that loads the most of its resources after onLoad event. So I can't rely on So I tried to track down, how many resources are loading at the moment by incrementing on the But the counter never got to zero in my case, cause I wonder if there is another efficient way to wait until the page is completely loaded. |
@igormukhin: If the page happens to be using jQuery for its AJAX calls, you could add an $(document).ajaxStop(function() {
if (typeof window.callPhantom === 'function') {
window.callPhantom({ name: 'ajaxStop' });
}
}); Then just add a page.onCallback = function(data) {
if (data && data.name === 'ajaxStop') {
setTimeout(function() {
page.render('thisPage.png');
phantom.exit();
}, 200);
}
}; |
@JamesMGreene Thanks for the hint. I missed that reading the docs. If I could change the page's code or be always sure it uses only jQuery for its requests, I could rely on that. But, I think, counting the starting requests and ending responses is more reliable for purposes of making screenshots. |
I'm seeing the opposite as well, where only the OnResourceReceived is called but onResourceRequested is not. |
I investigated the problem and this is qwebkit issue - the same things happends on Qt objects level, finished() signals are not emmited never for AJAX requests. Well in Qt problem is the same, it's not phantomjs bug, but finished() singnals are not emitted by Qt objects for AJAX requests. Situation presents this way:
Why this happends? That's because webkit AJAX requester manager destroys QNetworkReply object very fast handly, in above situations QNetworkReply::destroyed() is called before QNetworkReply::finished() signal is processed (I guess webkit code calls delete, not deleteLater() on QNetworkReply object which destroys it immediately without possible to process finishing signals). My solution is to call onFinished() or onError() signals methods handly, in QNetworkReply::destroyed() method slot if they weren't before, this makes sure to fire finishing slots allways for every QNetworkReply object. void MyNetworkRequest::onTimeouted() {
if(this->isActive()) {
this->data.time.end = QDateTime::currentDateTime().toTime_t();
this->data.state = TIMEOUTED;
this->data.error.code = TIMEOUT_ERROR_CODE;
this->data.error.text = "Request respond timeouted";
this->reply->abort(); /* this crashed me before because this->reply is deleted here which I didn't know, now onFinished() or onFailed() shotsdown timeout timers correctly before object destroy */
this->supportDelayedRequestToFile();
emit requestStateChange(this);
}
}
void MyNetworkRequest::onFree() { /* slot connected with QNetworkReply::destroyed() */
if(this->isActive()) { /* isActive means request is not ended, finished() or error() wasn't fired before, but object will be delete for a moment */
/* this is fix for AJAX requests, QNetworkReply* is correctly setup here, fire signals finished() or error(QNetworkReply::NetworkError) handly before object destroying */
if(this->reply->error() == QNetworkReply::NoError) this->onFinished();
else this->onFailed(this->reply->error());
}
}```
I know that new version PhantomJS 2 under Qt5 is created but this problem exists also in Qt5. |
Hey @crayze, sorry to disturb, I'm wondering if you could make a pull request to the project with your solution in order to get this bug fixed? |
This is Qt network level simple example code to fix this problem (destroying QNetworkReply object before finishing signals execution)
|
Due to our very limited maintenance capacity, we need to prioritize our development focus on other tasks. Therefore, this issue will be automatically closed (see #15395 for more details). In the future, if we see the need to attend to this issue again, then it will be reopened. Thank you for your contribution! |
Which version of PhantomJS are you using?
phantomjs-1.9.0 (Windows)
What steps will reproduce the problem?
a) a page with jQuery.ajax({ url: ..., async: false });
b) open this page in phantomjs
What is the expected output? What do you see instead?
expected: OnResourceReceived should be fired
happens: OnResourceReceived never fired for this resource
The text was updated successfully, but these errors were encountered: